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

前言:web

Spring的AppilcaitionContext可以發佈事件和註冊相對應的事件監聽器,所以,它有一套完整的事件發佈和監聽機制。spring

流程分析:app

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

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

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

3. 事件監聽器註冊表:就是spring框架爲全部的監聽器提供了一個存放的地方;測試

經過流程圖,能夠看出它們是如何各司其職的,以下:this

其實經過流程圖,咱們很容易發現事件體系就是觀察者模式的具體實現,它並無任何的神祕之處。spa

結構分析:code

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"/>

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

相關文章
相關標籤/搜索