SyncTaskExecutor来执行listener的注册event,所有该listener注册的event事件为同步执行的)。

当然,spring的这个机制还有很多应用的场景,就不一一列举了。

ApplicationEvent

事件抽象类,里面只有一个构造函数和一个timestamp。

ApplicationListener

监听接口,里面只有一个onApplicationEvent方法。需要用户自己编写ApplicationListener的实现。

ApplicationContext

spring上下文,其publishEvent方法用于通知监听器(ApplicationListener的实现)注册event时间.

publishEvent

void publishEvent(ApplicationEvent event)



Notify all listeners registered with this application of an application event.

源码解读:
1.作为ApplicationContext的实现AbstractApplicationContext.java的成员变量applicationListeners,是一个ArrayList,保存了所有的ApplicationListener
2.利用ApplicationEventMulticaster接口里的方法来完成注册监听addApplicationListener,移除监听removeApplicationListener,removeAllListeners,以及通知监听注册事件event:multicastEvent(ApplicationEvent event);
上面说到的publishEvent方法即使用了multicastEvent方法

SimpleApplicationEventMultucaster作为ApplicationEventMulticaster的一个实现,提供了multicastEvent的实现代码,其实就是迭代所有的监听器,用SyncTaskExecutor同步执行listener的onApplicationEvent

public void multicastEvent(final ApplicationEvent event) {
for (Iterator it = getApplicationListeners().iterator(); it
.hasNext();) {
final ApplicationListener listener = (ApplicationListener) it
.next();
getTaskExecutor().execute(new Runnable() {
public void run() {
listener.onApplicationEvent(event);
 }
 });
 }onApplicationEvent)。原因就是multicastEvent的执行原理。它是迭代执行所有的监听器onApplicationEvent
这里是ApplicationEventMulticaster的类分布图
 abstract public class AbstractApplicationEventMulticaster implements ApplicationEventMulticaster(Code)(Java Doc)
 public interface ApplicationEventMulticaster (Code)(Java Doc) public class SimpleApplicationEventMulticaster extends
 这里是ApplicationContext的类分布图
 public class DefaultResourceLoader implements ResourceLoader(Code)(Java Doc)
 public interface ResourceLoader (Code)(Java Doc) abstract public class AbstractApplicationContext extends DefaultResourceLoader implements ConfigurableApplicationContext,DisposableBean(Code)(Java Doc)
 public interface ConfigurableApplicationContext extends ApplicationContext,Lifecycle(Code)(Java Doc)
 public interface DisposableBean (Code)(Java Doc) public class GenericApplicationContext extends AbstractApplicationContext implements BeanDefinitionRegistry(Code)(Java Doc)
 public interface BeanDefinitionRegistry (Code)(Java Doc) abstract public class AbstractRefreshableApplicationContext extends


下面是spring自身的事件应用
1) ContextRefreshedEvent:当ApplicationContext初始化或者刷新时触发该事件。
2) ContextClosedEvent:当ApplicationContext被关闭时触发该事件。容器被关闭时,其管理的所有单例Bean都被销毁。
3) RequestHandleEvent:在Web应用中,当一个http请求(request)结束触发该事件。
4) ContestStartedEvent:当容器调用ConfigurableApplicationContext的Start()方法开始/重新开始容器时触发该事件。
5) ContestStopedEvent:当容器调用ConfigurableApplicationContext的Stop()方法停止容器时触发该事件。






用一个简单的例子来实现spring事件监听的功能

 

这个例子主要功能是,记录那些用户是第一次登入系统,如果用户是第一次登入系统,则调用spring的事件监听,记录这些用户。

 

主要用到的spring的类和接口有:

   org.springframework.context.event.ApplicationEvent抽象类及其子类来实现事件;

   org.springframework.context.ApplicationListener接口及其实现者实现事件的监听。

 这两者构成了观察者模式(Observer)。

 

 通过org.springframework.context.ApplicationContextAware接口的实现类,可以取得ApplicationContext, AlicationContext提供了publishEvent方法,实现事件的发布。

 

下面让我们来看下实现代码:

 

1 自定义事件 继承ApplicationEvent抽象类

   ApplicationEvent 她继承自java.util.EventObject,其中仅仅创建了一个构造器ApplicationEvent,和一个取得当前系统事件的timestamp

 

 

public class FirstLoginUserEvent extends ApplicationEvent{
  
            private String loginName;
   
            public FirstLoginUserEvent(Object source){
                 super(source);
            }
  
            public FirstLoginUserEvent(Object source, String loginName){
                 super(source);
                 this.loginName=loginName;
                 System.out.println(super.getTimestamp());
                 System.out.println(loginName);               
            }
  
            public String getLoginName(){
                  return loginName;
            }
  
            public void setLoginName(String loginName){
                  this.loginName=loginName;
            }
    }

 2 定义监听器 继承ApplicationListener接口

 

 

@Service("firstLoginUserListener ")
     public class FirstLoginUserListener implements ApplicationListener{
          
            private static Log log = LogFactory.getLog(FirstLoginUserListener.class);
  
            public void onApplicationEvent(ApplicationEvent event) {
                   if (event instanceof FirstLoginUserEvent){
                          FirstLoginUserEvent  firstLoginUserEvent=(FirstLoginUserEvent)
                          log.debug("用户:"+firstLoginUserEvent.getLoginName()+"第一次登入");
                   }else{
                          log.debug("其它事件");
                    }
            }     
      }
  
  3 发布事件
    
     @Service("userService ")
     public class UserService implements ApplicationContextAware {
           
           private ApplicationContext applicationContext;
  
   public void setApplicationContext (ApplicationContext applicationContext){
                  this.applicationContext=applicationContext;
          }
  
           public void decideUser(int num,String loginName){
                if (num==0){ //用户第一次登入,发布事件
                       applicationContext.publishEvent(new FirstLoginUserEvent(this,loginName));
                }else{
                       .......
                }
           }
     }

 

当我们发布事件的时候,我们的监听器就会对这个事件进行监听。