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

Spring---ApplicationContext的事件機制

ApplicationContext的事件機制簡介

1,事件源:ApplicationContext.publishEvent()方法:用於主動觸發容器事件


2,事件:ApplicationEvent類,容器事件,必須由ApplicationContext釋出(實際應用時,容器事件除了繼承了ApplicationEvent類外,其實它就是一個普通的Java類


3,事件監聽器:ApplicationListener介面,可由容器中任何監聽器Bean擔任。onApplicationEvent(ApplicationEvent event):用於對事件的處理每當容器內發生任何事件時,此方法都被觸發。

 

這三者是什麼關係?

ApplicationContext 通過publishEvent方法(該方法繼承於介面ApplicationEventPublisher)釋出事件(ApplicaitonEvent), 然後由ApplicationListener監聽處理。 


實際上,Spring的事件機制與所有時間機制都基本相似,它們都需要事件源事件事件監聽器組成。

只是此處的事件源是ApplicationContext,且事件必須由Java程式顯式觸發。下面的程式將演示Spring容器的事件機制。

 

事件機制一個例子

 1,先定義了一個ApplicationEvent類,其物件就是一個Spring容器事件,程式碼如下:

public class EmailEvent extends ApplicationEvent{
   private String address;
   private String text;
   public EmailEvent(Object source, String address, String text){
       super(source);
     this.address = address;
     this.text = text;
   }
   public EmailEvent(Object source) {
     super(source);
   }
   //......address和text的setter、getter
}

上面的EmailEvent類繼承了ApplicationEvent類,除此之外,它就是一個普通的Java類。


2,容器監聽器類程式碼如下:

public class EmailNotifier implements ApplicationListener {
    @Override
    public void onApplicationEvent(ApplicationEvent applicationEvent) {
        if (applicationEvent instanceof EmailEvent){
            EmailEvent emailEvent = (EmailEvent) applicationEvent;
            System.out.println("需要傳送郵件的接收地址: " + emailEvent.getAddress());
            System.out.println("需要傳送郵件的郵件正文: " + emailEvent.getText());
        }else {
            System.out.println("容器本身的事件: " + applicationEvent);
        }
    }
}

容器事件的監聽器類必須實現 ApplicationListener 介面,並複寫 onApplicationEvent() 方法

  • onApplicationEvent(ApplicationEvent event):每當容器內發生任何事件時,此方法都會被觸發

3,將監聽器配置在Spring的容器中,程式碼如下:

<bean class="org.spring.listener.EmailNotifier"/>

為Spring容器註冊監聽器,不需要像AWT程式設計那樣採用程式碼進行註冊,只需要在Spring的配置檔案中進行簡單配置即可。當我們在Spring中配置了一個實現了ApplicationListener的BeanSpring容器就會把這個Bean當成容器事件的監聽器


4,主動觸發容器事件,程式碼如下:

public class SpringTest {
    public static void main(String[] args){
        ApplicationContext ctx = new ClassPathXmlApplicationContext("spring-config.xml");
        //建立一個ApplicationEvent物件
        //EmailEvent ele = new EmailEvent("hello","[email protected]","this is a test");
        //主動觸發該事件
        //ctx.publishEvent(ele);
    }
}

當系統建立Spring容器載入Spring容器時會自動觸發容器事件容器事件監聽器可以監聽到這些事件。除此之外,程式也可以呼叫 ApplicationContext 的 publishEvent()方法主動觸發一個容器事件


5,程式到此結束,執行結果如下:

容器本身的事件: org.springframework.context.event.ContextRefreshedEvent[source=org[email protected]b81eda8: startup date [Thu Dec 04 20:20:52 CST 2014]; root of context hierarchy]


6,若取消main中的註釋,即,使用publishEvent()來觸發事件,執行結果如下:

容器本身的事件: org.springframework.context.event.ContextRefreshedEvent[source=org[email protected]b81eda8: startup date [Thu Dec 04 20:24:03 CST 2014]; root of context hierarchy]

需要傳送郵件的接收地址: [email protected]

需要傳送郵件的郵件正文: this is a test

注意:如果Bean想釋出事件,則Bean必須獲得其容器的引用。如果程式中沒有直接獲取容器的引用,則應該讓Bean實現ApplicationContextAware或者BeanFactoryAware介面,從而可以獲得容器的引用。

 

 

詳細介紹

ApplicationContext事件機制是觀察者設計模式的實現,通過ApplicationEvent類ApplicationListener介面,可以實現ApplicationContext事件處理。

ApplicationListener Bean,每當ApplicationContext釋出ApplicationEvent時,ApplicationListener Bean將自動被觸發

Spring的事件框架有如下兩個重要的成員:

  • ApplicationEvent:容器事件,必須由ApplicationContext釋出
  • ApplicationListener:監聽器,可由容器中的任何監聽器Bean擔任

 

擴充套件瞭解:Spring提供如下幾個內建事件:

  • ContextRefreshedEvent:ApplicationContext容器初始化或重新整理時觸發該事件。此處的初始化是指:所有的Bean被成功裝載,後處理Bean被檢測並激活,所有Singleton Bean 被預例項化,ApplicationContext容器已就緒可用
  • ContextStartedEvent:當使用ConfigurableApplicationContext(ApplicationContext的子介面)介面的start()方法啟動ApplicationContext容器時觸發該事件。容器管理宣告週期的Bean例項將獲得一個指定的啟動訊號,這在經常需要停止後重新啟動的場合比較常見(https://www.cnblogs.com/weilunhui/p/4143793.html
  • ContextClosedEvent:當使用ConfigurableApplicationContext介面的close()方法關閉ApplicationContext時觸發該事件
  • ContextStoppedEvent:當使用ConfigurableApplicationContext介面的stop()方法使ApplicationContext容器停止時觸發該事件。此處的停止,意味著容器管理生命週期的Bean例項將獲得一個指定的停止訊號,被停止的Spring容器可再次呼叫start()方法重新啟動
  • RequestHandledEvent:Web相關事件,只能應用於使用DispatcherServlet的Web應用。在使用Spring作為前端的MVC控制器時,當Spring處理使用者請求結束後,系統會自動觸發該事件。

 


參考來源:

https://www.cnblogs.com/weilunhui/p/4143793.html

https://blog.csdn.net/maywehe/article/details/51660972

http://www.importnew.com/20890.html