Spring中ApplicationContext的事件機制
阿新 • • 發佈:2019-01-11
ApplicationContext事件機制是觀察者設計模式的 實現,通過ApplicationEvent類和ApplicationListener介面,可以實現ApplicationContext事件處理。 如果容器中有一個ApplicationListener Bean,每當ApplicationContext釋出ApplicationEvent時,ApplicationListener Bean將自動被觸發。 Spring的事件框架有如下兩個重要的成員: ApplicationEvent:容器事件,必須由ApplicationContext釋出; ApplicationListener:監聽器,可由容器中的任何監聽器Bean擔任。 實際上,Spring的事件機制與所有時間機制都基本相似,它們都需要事件源、事件和事件監聽器組成。只是此處的事件源是 ApplicationContext,且事件必須由Java程式顯式觸發。下面的程式將演示Spring容器的事件機制。 Spring框架事先定義了一個 ApplicationEvent類,其物件就是一個Spring容器事件,其原始碼中的解釋是:Class to be extended by all application events. Abstract as itdoesn't make sense for generic events to be published directly.
程式碼如下:
package com.cxg.test.springPlatfrom;
import org.springframework.context.ApplicationEvent;
/**
* Title: email之事件類
* EmailEvent類繼承了ApplicationEvent類,除此之外,它就是一個普通的Java類
* Description: dataPlatfrom
* @author: xg.chen
* @date:2016年8月24日
*/
public class EmailEvent extends ApplicationEvent{
private static final long serialVersionUID = 1L;
//屬性
private String address;
private String text;
//構造方法
public EmailEvent(Object source) {
super(source);
}
public EmailEvent(Object source, String address, String text) {
super(source);
this.address = address;
this .text = text;
}
//getter和setter設定
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public String getText() {
return text;
}
public void setText(String text) {
this.text = text;
}
}
上面的EmailEvent類繼承了ApplicationEvent類,除此之外,它就是一個普通的Java類。
容器事件的監聽器類必須實現ApplicationListener介面,實現該介面就必須實現如下方法:onApplicationEvent(ApplicationEvent event):每當容器內發生任何事件時,此方法都會被觸發。在Spring原始碼中給出的解釋是:Interface to be implemented by application event listeners. Based on the standard {@code java.util.EventListener} interface for the Observer design pattern.
容器監聽器類程式碼如下:
package com.cxg.test.springPlatfrom;
import org.springframework.context.ApplicationEvent;
import org.springframework.context.ApplicationListener;
/**
* Title: email之監聽類
* 容器事件的監聽器類必須實現ApplicationListener介面,實現該介面就必須實現
* Description: dataPlatfrom
* @author: xg.chen
* @date:2016年8月24日
*/
public class EmailNotifier implements ApplicationListener<ApplicationEvent>{
@Override
public void onApplicationEvent(ApplicationEvent event) {
if(event instanceof EmailEvent){
EmailEvent emailEvent = (EmailEvent) event;
System.out.println("email's address:"+emailEvent.getAddress());
System.out.println("email's text:"+emailEvent.getText());
} else {
System.out.println("the Spring's event:"+event);
}
}
}
將監聽器配置在Spring的容器中,程式碼如下:
<!-- 配置事件監聽 -->
<bean class="com.cxg.test.springPlatfrom.EmailNotifier" />
為Spring容器註冊監聽器,不需要像AWT程式設計那樣採用程式碼進行註冊,只需要在Spring的配置檔案中進行簡單配置即可。當我們住唉 Spring中配置了一個實現了ApplicationListener的Bean,Spring容器就會把這個Bean當成容器事件的監聽器。當系統建立Spring容器、載入Spring容器時會自動觸發容器事件,容器事件監聽器可以監聽到這些事件。除此之外,程式也可以呼叫ApplicationContext的publishEvent()方法來主動觸發一個容器事件。
測試程式碼如下:
package com.cxg.test.springPlatfrom;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
/**
* Title: Spring的ApplicationContexet單元成測試
* Description: dataPlatfrom
* @author: xg.chen
* @date:2016年8月24日
*/
public class SpringTest {
public static void main(String arg[]){
//讀取Spring容器的配置檔案
@SuppressWarnings("resource")
ApplicationContext applicationContext=new ClassPathXmlApplicationContext("application.xml");
//建立一個事件物件
EmailEvent emailEvent = new EmailEvent("hello Spring!", "[email protected]", "This is SpringApplicatoinContext test!");
//主動觸發事件監視機制
applicationContext.publishEvent(emailEvent);
}
}
執行輸出:
email's address:[email protected]126.com
email's text:This is SpringApplicatoinContext test!
注意:如果Bean想釋出事件,則Bean必須獲得其容器的引用。如果程式中沒有直接獲取容器的引用,則應該讓Bean實現ApplicationContextAware或者BeanFactoryAware介面,從而可以獲得容器的引用。
Spring提供如下幾個內建事件:
ContextRefreshedEvent:ApplicationContext容器初始化或重新整理時觸發該事件。此處的初始化是指:所有的 Bean被成功裝載,後處理Bean被檢測並激活,所有Singleton Bean 被預例項化,ApplicationContext容器已就緒可用。
ContextStartedEvent:當使用 ConfigurableApplicationContext(ApplicationContext的子介面)介面的start()方法啟動 ApplicationContext容器時觸發該事件。容器管理宣告週期的Bean例項將獲得一個指定的啟動訊號,這在經常需要停止後重新啟動的場合比 較常見。
ContextClosedEvent:當使用ConfigurableApplicationContext介面的close()方法關閉ApplicationContext時觸發該事件。
ContextStoppedEvent:當使用ConfigurableApplicationContext介面的stop()方法使 ApplicationContext容器停止時觸發該事件。此處的停止,意味著容器管理生命週期的Bean例項將獲得一個指定的停止訊號,被停止的 Spring容器可再次呼叫start()方法重新啟動。
RequestHandledEvent:Web相關事件,只能應用於使用DispatcherServlet的Web應用。在使用Spring作為前端的MVC控制器時,當Spring處理使用者請求結束後,系統會自動觸發該事件。