spring事件驅動模型學習整理
我們在使用spring進行開發的時候,會有一些這樣的需求,就是當我們在某些事件發生後,對這些事件有對應的相應來進行數據處理。以往可能會通過觀察者模式來進行相關的實現,被觀察者實現相關的事件,而觀察者訂閱被觀察者的事件來完成我們想要處理的邏輯。那麼我們還有沒有什麼方式來達到同樣的效果呢?其實是有的,spring內部提供了事件響應機制我們可以直接就哪來使用,spring是不是很強大,我們有跟多功能可以來用,但這個前提是我們要不斷對spring進行深挖,好了,下面我們來說說spring的事件模型,使用事件模型非常方便,我們只要以下幾個步驟就可以了。
1.實現自定義事件集成ApplicationEvent類。
2.在業務類中定義上面自定義的事件類,然後通過ApplicationContext發佈publishEvent
發佈我們定義的事件。
3.自定義監聽接口實現ApplicationListener<自定義Event>實現具體的響應邏輯。注意這裏
邏輯可以異步執行 @Async。
通過以上3個步驟就可以完成事件通知的處理方式,是不是很牛,但這不是所有,spring同樣提供了更加智能的監聽程序,可以完成更高級的一些需求,SmartApplicationListener這類可以指定更多的約定,更安全的實現業務邏輯。這個接口可以決定的有以下內容:
1.約定支持的事件類型。
2.約定事件的參數類型。
3.約定事件的優先級。
4.約定事件的業務邏輯。
applicationContext.publishEvent()方法,需要同步等待各個監聽器處理完之後,才返回。也就是說,Spring提供的事件機制,默認是同步的。如果想用異步的,可以自己實現ApplicationEventMulticaster接口,並在Spring容器中註冊id爲applicationEventMulticaster的Bean。ApplicationContext的發佈事件,ApplicationContext自動到本地容器裏找一個名字爲
ApplicationEventMulticaster實現,如果沒有自己new一個SimpleApplicationEventMulticaster。其中SimpleApplicationEventMulticaster也是AbstractApplicationEventMulticaster類唯一的默認實現,我們可以直接new一個SimpleApplicationEventMulticaster並制定bean的名稱爲applicationEventMulticaster即可,想要改爲異步僅需要傳入對應的Executor即可。
/**
* Initialize the ApplicationEventMulticaster.
* Uses SimpleApplicationEventMulticaster if none defined in the context.
* @see org.springframework.context.event.SimpleApplicationEventMulticaster
*/
protected void initApplicationEventMulticaster() {
ConfigurableListableBeanFactory beanFactory = getBeanFactory();
if (beanFactory.containsLocalBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME)) {
this.applicationEventMulticaster =
beanFactory.getBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, ApplicationEventMulticaster.class);
if (logger.isTraceEnabled()) {
logger.trace("Using ApplicationEventMulticaster [" + this.applicationEventMulticaster + "]");
}
}
else {
this.applicationEventMulticaster = new SimpleApplicationEventMulticaster(beanFactory);
beanFactory.registerSingleton(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, this.applicationEventMulticaster);
if (logger.isTraceEnabled()) {
logger.trace("No '" + APPLICATION_EVENT_MULTICASTER_BEAN_NAME + "' bean, using " +
"[" + this.applicationEventMulticaster.getClass().getSimpleName() + "]");
}
}
}
/**
* Name of the ApplicationEventMulticaster bean in the factory.
* If none is supplied, a default SimpleApplicationEventMulticaster is used.
* @see org.springframework.context.event.ApplicationEventMulticaster
* @see org.springframework.context.event.SimpleApplicationEventMulticaster
*/
public static final String APPLICATION_EVENT_MULTICASTER_BEAN_NAME = "applicationEventMulticaster";
以上是AbstractApplicationContext類中的默認初始化過程,我們看是不是很清楚,他默認沒有指定線程池,而直接創建了對應的對象,所以直接使用的是同步的方式,那麼我們在使用的時候需要根據實際業務進行傳遞相應的線程模型來實現異步執行。