寫在前面的話:spring的監聽事件模型應該是觀察者模式。本人項目里的應用在process方法按日期同步某個庫的數據,在方法最后publish一個event事件,這個事件用于后續同步過來的數據處理。事件處理采用了spring的監聽模型.這樣可以做到process方法與event可以異步分離執行。(注:這個事件模型缺省使用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);
}
});
}
3.注意事項:自己編寫ApplicationListener的實現時,要注意不同的監聽器處理不同的事件(復寫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()方法停止容器時觸發該事件。