1. 程式人生 > >Spring中ApplicationContext的事件機制

Spring中ApplicationContext的事件機制

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處理使用者請求結束後,系統會自動觸發該事件。