`
enjiex
  • 浏览: 67101 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

Spring事件机制

阅读更多
Java提供了事件机制,在使用spring的时候,我们可以把普通的java事件操作定义为bean集成到bean容器中,但还有一种更方便的方式,即使用spring已集成的事件支持。
在使用Spring的事件支持时,我们需要关注以下几个对象:
      1. ApplicationEvent:继承自EventObject,同时是spring的application中事件的父类,需要被自定义的事件继承。
      2. ApplicationListener:继承自EventListener,spring的application中的监听器必须实现的接口,需要被自定义的监听器实现其onApplicationEvent方法
      3. ApplicationEventPublisherAware:在spring的context中希望能发布事件的类必须实现的接口,该接口中定义了设置ApplicationEventPublisher的方法,由ApplicationContext调用并设置。在自己实现的ApplicationEventPublisherAware子类中,需要有ApplicationEventPublisher属性的定义。
      4. ApplicationEventPublisher:spring的事件发布者接口,定义了发布事件的接口方法publishEvent。因为ApplicationContext实现了该接口,因此spring的ApplicationContext实例具有发布事件的功能(publishEvent方法在AbstractApplicationContext中有实现)。在使用的时候,只需要把ApplicationEventPublisher的引用定义到ApplicationEventPublisherAware的实现中,spring容器会完成对ApplicationEventPublisher的注入。

在spring的bean配置中,因为事件是由事件源发出的,不需要注册为bean由spring容器管理。所以在spring的配置中,只需配置自定义的ApplicationEventListener和publisherAware(即实现了ApplicationEventPublisherAware接口的发布类),而对于ApplicationEventPublisher的管理和注入都由容器来完成。

基于spring的事件简单实现如下:
1. 定义ApplicationEvent
package com.nuc.event;

import org.springframework.context.ApplicationEvent;
/**
 * 定义Spring容器中的事件,与java普通的事件定义相比,只是继承的父类不同而已,在
 * 在定义上并未有太大的区别,毕竟ApplicationEvent也是继承自EventObject的。
 */
public class MethodExecutionEvent extends ApplicationEvent {

    private static final long serialVersionUID = 2565706247851725694L;
    private String methodName;
    private MethodExecutionStatus methodExecutionStatus;
    
    public MethodExecutionEvent(Object source) {
        super(source);
    }
    
    public MethodExecutionEvent(Object source, String methodName, MethodExecutionStatus methodExecutionStatus) {
        super(source);
        this.methodName = methodName;
        this.methodExecutionStatus = methodExecutionStatus;
    }

    public String getMethodName() {
        return methodName;
    }

    public void setMethodName(String methodName) {
        this.methodName = methodName;
    }

    public MethodExecutionStatus getMethodExecutionStatus() {
        return methodExecutionStatus;
    }

    public void setMethodExecutionStatus(MethodExecutionStatus methodExecutionStatus) {
        this.methodExecutionStatus = methodExecutionStatus;
    }
}

2. 定义ApplicationEventListener
package com.nuc.listener;

import org.springframework.context.ApplicationEvent;
import org.springframework.context.ApplicationListener;

import com.nuc.event.MethodExecutionEvent;
import com.nuc.event.MethodExecutionStatus;
/**
 * Spring容器中的事件监听器,与java中基本的事件监听器的定义相比,这里需要实现ApplicationListener接口
 * ApplicationListener接口虽然继承自EventListener,但扩展了EventListener
 * 它在接口声明中定义了onApplicationEvent的接口方法,而不像EventListener只作为标记性接口。
 */

public class MethodExecutionEventListener implements ApplicationListener {

    public void onApplicationEvent(ApplicationEvent event) {
        if (event instanceof MethodExecutionEvent) {
           if (MethodExecutionStatus.BEGIN
                    .equals(((MethodExecutionEvent) event)
                            .getMethodExecutionStatus())) {
                System.out.println("It's beginning");
            }
            if (MethodExecutionStatus.END.equals(((MethodExecutionEvent) event).getMethodExecutionStatus())) {
                System.out.println("It's ending");
            }
        }
    }
}

3. 定义ApplicationEventPublisherAware
package com.nuc.publisher;

import org.springframework.context.ApplicationEventPublisher;
import org.springframework.context.ApplicationEventPublisherAware;

import com.nuc.event.MethodExecutionEvent;
import com.nuc.event.MethodExecutionStatus;

public class MethodExecutionEventPublisher implements
        ApplicationEventPublisherAware {

    private ApplicationEventPublisher eventPublisher;
    
    public void methodToMonitor() {
        MethodExecutionEvent beginEvent = new MethodExecutionEvent(this, "methodToMonitor", MethodExecutionStatus.BEGIN);
        this.eventPublisher.publishEvent(beginEvent);
        //TODO
        MethodExecutionEvent endEvent = new MethodExecutionEvent(this, "methodToMonitor", MethodExecutionStatus.END);
        this.eventPublisher.publishEvent(endEvent);
    }
    
    public void setApplicationEventPublisher(
            ApplicationEventPublisher applicationEventPublisher) {
        this.eventPublisher = applicationEventPublisher;
    }
}

4. 定义bean配置
<?xml version="1.0" encoding="GBK"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd"
	default-autowire="byName">
	<bean id="methodExecListener" class="com.nuc.listener.MethodExecutionEventListener"></bean>
	<bean id="evtPublisher" class="com.nuc.publisher.MethodExecutionEventPublisher"></bean>	
</beans>

5. 使用事件
package com.nuc;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import com.nuc.publisher.MethodExecutionEventPublisher;

public class App 
{
    public static void main( String[] args )
    {
        ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
        MethodExecutionEventPublisher publisher = (MethodExecutionEventPublisher)context.getBean("evtPublisher");
        publisher.methodToMonitor();
    }
}


从实现来上,和使用基本的java事件流程大体一致,不同的是这里不需要自定义发布者,而使用spring实现提供的事件发布实现。当然,这里却引入了ApplicationEventPublisherAware。
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics