【好文推薦】Spring中ApplicationContext的事件機制

ApplicationContext事件機制是觀察者設計模式的實現,通過ApplicationEvent類和ApplicationListener接口,可以實現ApplicationContext

事件處理。如果容器中有一個ApplicationListener Bean,每當ApplicationContext發佈ApplicationEvent時,ApplicationListener Bean將自動被

觸發。

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

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

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

且事件必須由Java程序顯式觸發。下面的程序將演示Spring容器的事件機制。程序先定義了一個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類。

容器事件的監聽器類必須實現ApplicationListener接口,實現該接口就必須實現如下方法:

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

本例所使用的容器監聽器類代碼如下:

public class EmailNotifier implements ApplicationListener{
   public void onApplicationEvent(ApplicationEvent event) {
     if (event instanceof EmailEvent) {
        EmailEvent emailEvent = (EmailEvent)event;
        System.out.println("郵件地址:" + emailEvent.getAddress());
        System.our.println("郵件內容:" + emailEvent.getText());
     } else {
        System.our.println("容器本身事件:" + event);
     }
   }
}

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

<bean class="com.abc.EmailNotifier" />

爲Spring容器註冊監聽器,不需要像AWT編程那樣採用代碼進行註冊,只需要在Spring的配置文件中進行簡單配置即可。當我們在

Spring中配置了一個實現了ApplicationListener的Bean,Spring容器就會把這個Bean當成容器事件的監聽器。

當系統創建Spring容器、加載Spring容器時會自動觸發容器事件,容器事件監聽器可以監聽到這些事件。除此之外,程序也可以

調用ApplicationContext的publishEvent()方法來主動觸發一個容器事件,如下是一個例子:

public class SpringTest {
   public static void main(String args[]){
     ApplicationContext context = new ClassPathXmlApplicationContext("bean.xml");
     //創建一個ApplicationEvent對象
     EmailEvent event = new EmailEvent("hello","[email protected]","This is a test");
     //主動觸發該事件
     context.publishEvent(event);
   }
}

注意:如果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處理用戶請求結束後,系統會自動觸發該事件。

原文出處: chenssy

發佈了80 篇原創文章 · 獲贊 690 · 訪問量 67萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章