1. 程式人生 > >spring 自定義事件發布及監聽(簡單實例)

spring 自定義事件發布及監聽(簡單實例)

講解 new 繼承 概念 接口 處理 啟動 lca 事件對象

前言:

Spring的AppilcaitionContext能夠發布事件和註冊相對應的事件監聽器,因此,它有一套完整的事件發布和監聽機制。

流程分析:

在一個完整的事件體系中,除了事件監聽器以外,還應該有3個概念;

1. 事件源:事件的產生者,任何一個event都必須有一個事件源;

2. 事件廣播器:它是事件和事件監聽器之間的橋梁,負責把事件通知給事件監聽器;

3. 事件監聽器註冊表:就是spring框架為所有的監聽器提供了一個存放的地方;

通過流程圖,可以看出它們是如何各司其職的,如下:

技術分享圖片

其實通過流程圖,我們很容易發現事件體系就是觀察者模式的具體實現,它並沒有任何的神秘之處。

結構分析:

1. 事件類ApplicaitonEvent):目前spring框架本身僅僅提供了幾個事件,很多的事件都是需要自定義的。

 ApplicationEvent唯一的構造函數是ApplicaitonEvent(Object source),通過source指定事件源。 它有兩個子類;

(1)ApplicationContextEvent:容器事件,也就是說事件源是ApplicationContext,框架提供了四個子類,分別代表容器啟動,刷新,停止和關閉事件。

(2)RequestHandleEvent:這是一個與Web應用相關的事件,當一個請求被處理後,才會產生該事件。

一般來說,我們都是擴展ApplicationEvent來自定義事件。下面會有栗子。

技術分享圖片

2. 事件監聽器接口ApplicationListener

所有的監聽器都需要實現該接口,該接口只定義了一個方法:onApplicaitonEvent (E event),該方法接收事件對象,在該方法中編寫事件的響應處理邏輯。

技術分享圖片

實例分析:

通過一個實例來講解事件發布和事件監聽的過程。這個例子包括一個模擬的郵件發送器MailSender,它在向目的地發送郵件的時候 會產生一個MailSendEvent事件,我們同時向容器中註冊了該事件的監聽器MailSendListener;

上代碼:MailSendEvent

/**
 * 繼承了ApplicationContextEvent,就是個容器事件
 
*/ public class MailSendEvent extends ApplicationContextEvent { private String to; //目的地 public MailSendEvent(ApplicationContext source, String to) { super(source); this.to = to; } public String getTo(){ return this.to; } }

很明顯,這裏的source是ApplicationContext容器。

我們再定義一個該事件的監聽器MailSendListener,如下

@Component
public class MailSendListener implements ApplicationListener<MailSendEvent>{
    @Override
    public void onApplicationEvent(MailSendEvent mailSendEvent) {
        MailSendEvent event = mailSendEvent;
        System.out.println("MailSender向"+ event.getTo()+ "發送了郵件");
    }
}

上述提及到所有的監聽器都必須要實現ApplicationListener,這裏是個泛型類,指定了該監聽器只監聽MailSendEvent事件。

OK,那我們現在來觸發事件:MailSender,也就是事件源

@Component("mailSender")
public class MailSender {
    @Autowired
    private ApplicationContext applicationContext;  //容器事件由容器觸發

    public void sendMail(String to){
        System.out.println("MailSender開始發送郵件");
        MailSendEvent event = new MailSendEvent(applicationContext,to);
        applicationContext.publishEvent(event);
    }
}

最後寫個測試類,容器啟動:

public class SpringEventTest {

    public static void main(String[] args) {
        ApplicationContext context = new ClassPathXmlApplicationContext("web/WEB-INF/applicationContext.xml");
        MailSender sender  = (MailSender)context.getBean("mailSender");
        sender.sendMail("北京");
    }
}

記得在applicationContext.xml裏面加上註解掃描啊,我這裏都是放在springEvent包裏的,所以加上 <context:component-scan base-package="springEvent"/>

好了,啟動容器,發送郵件:執行結果如下

技術分享圖片

spring 自定義事件發布及監聽(簡單實例)