Spring-事件体系

 Spring事件体系包括三个组件:事件,事件监听器,事件广播器。


事件:ApplicationEvent
事件监听器:ApplicationListener,对监听到的事件进行处理。
事件广播器:ApplicationEventMulticaster,将Springpublish的事件广播给所有的监听器。
Spring在ApplicationContext接口的抽象实现类AbstractApplicationContext中完成了事件体系的搭建。
AbstractApplicationContext拥有一个applicationEventMulticaster成员变 量,applicationEventMulticaster提供了容器监听器的注册表。
AbstractApplicationContext在refresh()这个容器启动方法中搭建了事件的基础设施。
[java]  view plain copy
  1. try {  
  2.      // Invoke factory processors registered as beans in the context.  
  3.      invokeBeanFactoryPostProcessors();  
  4.      // Register bean processors that intercept bean creation.  
  5.      registerBeanPostProcessors();  
  6.      // Initialize message source for this context.  
  7.      initMessageSource();  
  8.      // Initialize event multicaster for this context.  
  9.      initApplicationEventMulticaster();  
  10.      // Initialize other special beans in specific context subclasses.  
  11.      onRefresh();  
  12.      // Check for listener beans and register them.  
  13.      registerListeners();  
  14.      // Instantiate singletons this late to allow them to access the message source.  
  15.      beanFactory.preInstantiateSingletons();  
  16.      // Last step: publish corresponding event.  
  17.      publishEvent( new ContextRefreshedEvent( this));  
  18. }  
1、事件广播器的初始化:
[java]  view plain copy
  1. private void initApplicationEventMulticaster() throws BeansException {  
  2.       if (containsLocalBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME )) {  
  3.            this.applicationEventMulticaster = (ApplicationEventMulticaster)  
  4.                    getBean( APPLICATION_EVENT_MULTICASTER_BEAN_NAME ,   
  5.                                  ApplicationEventMulticaster.class );  
  6.            if (logger.isInfoEnabled()) {  
  7.                    logger.info("Using ApplicationEventMulticaster ["   
  8.                                      + this. applicationEventMulticaster + "]" );  
  9.             }  
  10.        }  
  11.        else {  
  12.            this.applicationEventMulticaster = new SimpleApplicationEventMulticaster();  
  13.            if (logger.isInfoEnabled()) {  
  14.                logger.info("Unable to locate ApplicationEventMulticaster with name '"+  
  15.                         APPLICATION_EVENT_MULTICASTER_BEAN_NAME +  
  16.                         "': using default [" + this .applicationEventMulticaster + "]");  
  17.             }  
  18.        }  
  19.  }  
 用户可以在配置文件中为容器定义一个自定义的事件广播器,只要实现ApplicationEventMulticaster就可以了,Spring会通过 反射的机制将其注册成容器的事件广播器,如果没有找到配置的外部事件广播器,Spring自动使用 SimpleApplicationEventMulticaster作为事件广播器。

2、注册事件监听器
[java]  view plain copy
  1. private void registerListeners () throws BeansException {  
  2.    // Do not initialize FactoryBeans here: We need to leave all regular beans  
  3.    // uninitialized to let post-processors apply to them!  
  4.   Collection listeners = getBeansOfType(ApplicationListener.class,true,false).values();  
  5.    for (Iterator it = listeners.iterator(); it.hasNext();) {  
  6.          addListener((ApplicationListener) it.next());  
  7.     }  
  8. }  
  9. protected void addListener(ApplicationListener listener) {  
  10.      getApplicationEventMulticaster().addApplicationListener(listener);  
  11. }  
 Spring根据反射机制,使用 ListableBeanFactory的 getBeansOfType方法,从BeanDefinitionRegistry中找出所有实现 org.springframework.context.ApplicationListener的Bean,将它们注册为容器的事件监听器,实际的操作就是将其添加到事件广播器所提供的监听器注册表中。

3、发布事件
[java]  view plain copy
  1. public void publishEvent(ApplicationEvent event) {  
  2.       Assert. notNull(event, "Event must not be null");  
  3.       if (logger .isDebugEnabled()) {  
  4.             logger .debug("Publishing event in context ["   
  5.                       + getDisplayName() + "]: " + event);  
  6.       }  
  7.       getApplicationEventMulticaster(). multicastEvent(event);  
  8.       if (this .parent != null) {  
  9.            this .parent .publishEvent(event);  
  10.       }  
  11. }  
AbstractApplicationContext的publishEvent方法中, Spring委托ApplicationEventMulticaster将事件通知给所有的事件监听器

4、Spring默认的事件广播器SimpleApplicationEventMulticaster
[java]  view plain copy
  1. public void multicastEvent( final ApplicationEvent event) {  
  2.      for (Iterator it = getApplicationListeners().iterator(); it.hasNext();) {  
  3.            final ApplicationListener listener = (ApplicationListener) it.next();  
  4.            getTaskExecutor().execute( new Runnable() {  
  5.                    public void run() {  
  6.                           listener.onApplicationEvent(event);  
  7.                    }  
  8.             });  
  9.       }  
  10.  }  
遍历注册的每个监听器,并启动来调用每个监听器的onApplicationEvent方法。
由于SimpleApplicationEventMulticaster的taskExecutor的实现类是 SyncTaskExecutor,因此,事件监听器对事件的处理,是同步进行的。

从代码可以看出,applicationContext.publishEvent()方法,需要同步等待各个监听器处理完之后,才返回。
也就是说,Spring提供的事件机制,默认是同步的。如果想用异步的,可以自己实现ApplicationEventMulticaster接口,并在Spring容器中注册id为 applicationEventMulticaster的Bean。
例子:
[java]  view plain copy
  1. public class AsyncApplicationEventMulticaster extends AbstractApplicationEventMulticaster {  
  2.     private TaskExecutor taskExecutor = new SimpleAsyncTaskExecutor();  
  3.   
  4.     public void setTaskExecutor(TaskExecutor taskExecutor) {  
  5.         this.taskExecutor = (taskExecutor != null ? taskExecutor : new SimpleAsyncTaskExecutor());  
  6.     }  
  7.   
  8.     protected TaskExecutor getTaskExecutor() {  
  9.         return this.taskExecutor;  
  10.     }  
  11.   
  12.     @SuppressWarnings("unchecked")  
  13.     public void multicastEvent(final ApplicationEvent event) {  
  14.         for (Iterator<ApplicationListener> it = getApplicationListeners().iterator(); it.hasNext();) {  
  15.             final ApplicationListener listener =  it.next();  
  16.             getTaskExecutor().execute(new Runnable() {  
  17.                 public void run() {  
  18.                     listener.onApplicationEvent(event);  
  19.                 }  
  20.             });  
  21.         }  
  22.     }  
  23. }  
spring配置:
[html]  view plain copy
  1. <bean id="applicationEventMulticaster"   
  2.           class="com.alibaba.chj.event.AsyncApplicationEventMulticaster" />  

Spring发布事件之后,所有注册的事件监听器,都会收到该事件,因此,事件监听器在处理事件时,需要先判断该事件是否是自己关心的。
Sping事件体系所使用的设计模式是:观察者模式。 ApplicationListener是观察者接口,接口中定义了onApplicationEvent方法,该方法的作用是对ApplicationEvent事件进行处理。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值