1. 程式人生 > >spring監聽器demo

spring監聽器demo

歡迎進入《一起學spring》系列博文第三篇,

spring容器的事件監聽機制,同樣有事件、事件源和監聽者。而spring中的事件需要繼承ApplicationEvent,監聽者需要繼承ApplicationListener。其他的基本和普通的事件監聽差不多。我們用示例說話!

1、這是spring的ApplicationEvent類的原始碼,我們可以看到它繼承了JDK中的EventObject,EventObject中只有一個Object型別的source屬性以及一個getSource方法。下面這個ApplicationEvent類只是增加了一個時間戳的屬性以及getTimeStamp的方法。

  1. package org.springframework.context;  
  2. import java.util.EventObject;  
  3. /** 
  4.  * Class to be extended by all application events. Abstract as it 
  5.  * doesn't make sense for generic events to be published directly. 
  6.  * 
  7.  * @author Rod Johnson 
  8.  * @author Juergen Hoeller 
  9.  */  
  10. public abstract class ApplicationEvent extends EventObject {  
  11.     /** use serialVersionUID from Spring 1.2 for interoperability */  
  12.     private static final long serialVersionUID = 7099057708183571937L;  
  13.     /** System time when the event happened */  
  14.     private final long timestamp;  
  15.     /** 
  16.      * Create a new ApplicationEvent. 
  17.      * @param source the component that published the event (never {@code null}) 
  18.      */  
  19.     public ApplicationEvent(Object source) {  
  20.         super(source);  
  21.         this.timestamp = System.currentTimeMillis();  
  22.     }  
  23.     /** 
  24.      * Return the system time in milliseconds when the event happened. 
  25.      */  
  26.     public final long getTimestamp() {  
  27.         return this.timestamp;  
  28.     }  
  29. }  

2、spring中的ApplicationListener原始碼;我們可以清楚地知道,這個類和我們自定義監聽器中的監聽器類基本一樣。

  1. public interface ApplicationListener<E extends ApplicationEvent> extends EventListener {  
  2.     /** 
  3.      * Handle an application event. 
  4.      * @param event the event to respond to 
  5.      */  
  6.     void onApplicationEvent(E event);  
  7. }  


下面回到我們的程式碼:

3、我的事件

  1. package com.huai.listener;  
  2. import org.springframework.context.ApplicationEvent;  
  3. public class MyEvent extends ApplicationEvent{  
  4.     private String text;  
  5.     public MyEvent(Object source) {  
  6.         super(source);  
  7.     }  
  8.     public void setText(String text){  
  9.         this.text = text;  
  10.     }  
  11.     public String getText(){  
  12.         return this.text;  
  13.     }  
  14. }  


4、我的監聽器

  1. package com.huai.listener;  
  2. import org.springframework.context.ApplicationEvent;  
  3. import org.springframework.context.ApplicationListener;  
  4. public class MyListener implements ApplicationListener<ApplicationEvent>{  
  5.     @Override  
  6.     public void onApplicationEvent(ApplicationEvent event) {  
  7.         if(event instanceof MyEvent){  
  8.             System.out.println("my event laungh");  
  9.         }else{  
  10.             System.out.println("other envet");  
  11.         }  
  12.     }  
  13. }  


5、測試類:

  1. package com.huai.listener;  
  2. import org.springframework.context.support.ClassPathXmlApplicationContext;  
  3. import org.springframework.context.*;  
  4. public class SpringTest {  
  5.     public static void main(String[] args) {  
  6.         ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");  
  7.         MyEvent event = new MyEvent("hello World");  
  8.         event.setText("hello");  
  9.         context.publishEvent(event);  
  10.     }  
  11. }  

仔細看上面的測試類,MyEvent類已經例項化,但MyListener類呢?我們並沒有例項化,那麼我們應該讓容器例項化,所以我們需要在spring的配置檔案中告訴spring容器,讓它幫我們例項化MyListener類。我們還應該注意到這條程式碼:context.publishEvent(event);作用是讓spring容器中的所有監聽器都知道有這樣一個事件發生了。在spring原始碼中的解釋是:Notify all listeners registered with this application of an application event. Events may be framework events (such as RequestHandledEvent) or application-specific events.

6、spring的配置檔案:我們在spring中配置了一個實現了ApplicationListener的Bean,Spring容器就會把這個bean當成容器事件的監聽器。

  1. <?xml version="1.0" encoding="UTF-8"?>  
  2. <beans xmlns="http://www.springframework.org/schema/beans"  
  3.     xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
  4.     xmlns:context="http://www.springframework.org/schema/context"  
  5.     xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"  
  6.     xsi:schemaLocation="http://www.springframework.org/schema/beans    
  7.            http://www.springframework.org/schema/beans/spring-beans-3.0.xsd    
  8.            http://www.springframework.org/schema/context    
  9.            http://www.springframework.org/schema/context/spring-context-3.0.xsd    
  10.            http://www.springframework.org/schema/aop    
  11.            http://www.springframework.org/schema/aop/spring-aop-3.0.xsd    
  12.            http://www.springframework.org/schema/tx     
  13.            http://www.springframework.org/schema/tx/spring-tx-3.0.xsd  
  14.            http://www.springframework.org/schema/mvc  
  15.            http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd">  
  16.     <bean class="com.huai.listener.MyListener"/>  
  17. </beans>  

執行結果為:

other envet
my event laungh

第一個是spring容器內建的事件;

第二個是我們自己的事件。

實際上,如果開發者需要在spring容器中初始化、銷燬時回撥自定義的方法,就可以通過上面的事件監聽器來實現。