javascript
SpringBoot中@EventListener注解的使用
一:背景
 在開(kāi)發(fā)工作中,會(huì)遇到一種場(chǎng)景,做完某一件事情以后,需要廣播一些消息或者通知,告訴其他的模塊進(jìn)行一些事件處理,一般來(lái)說(shuō),可以一個(gè)一個(gè)發(fā)送請(qǐng)求去通知,但是有一種更好的方式,那就是事件監(jiān)聽(tīng),事件監(jiān)聽(tīng)也是設(shè)計(jì)模式中發(fā)布-訂閱模式、觀察者模式的一種實(shí)現(xiàn)。
 觀察者模式:簡(jiǎn)單的來(lái)講就是你在做事情的時(shí)候身邊有人在盯著你,當(dāng)你做的某一件事情是旁邊觀察的人感興趣的事情的時(shí)候,他會(huì)根據(jù)這個(gè)事情做一些其他的事,但是盯著你看的人必須要到你這里來(lái)登記,否則你無(wú)法通知到他(或者說(shuō)他沒(méi)有資格來(lái)盯著你做事情)。
 對(duì)于 Spring 容器的一些事件,可以監(jiān)聽(tīng)并且觸發(fā)相應(yīng)的方法。通常的方法有 2 種,ApplicationListener 接口和@EventListener 注解。
二:簡(jiǎn)介
 要想順利的創(chuàng)建監(jiān)聽(tīng)器,并起作用,這個(gè)過(guò)程中需要這樣幾個(gè)角色:
 1、事件(event)可以封裝和傳遞監(jiān)聽(tīng)器中要處理的參數(shù),如對(duì)象或字符串,并作為監(jiān)聽(tīng)器中監(jiān)聽(tīng)的目標(biāo)。
 2、監(jiān)聽(tīng)器(listener)具體根據(jù)事件發(fā)生的業(yè)務(wù)處理模塊,這里可以接收處理事件中封裝的對(duì)象或字符串。
 3、事件發(fā)布者(publisher)事件發(fā)生的觸發(fā)者。
三:ApplicationListener 接口
 ApplicationListener 接口的定義如下:
它是一個(gè)泛型接口,泛型的類型必須是 ApplicationEvent 及其子類,只要實(shí)現(xiàn)了這個(gè)接口,那么當(dāng)容器有相應(yīng)的事件觸發(fā)時(shí),就能觸發(fā) onApplicationEvent 方法。ApplicationEvent 類的子類有很多,Spring 框架自帶的如下幾個(gè)。
使用方法很簡(jiǎn)單,就是實(shí)現(xiàn)一個(gè) ApplicationListener 接口,并且將加入到容器中就行。
@Component public class MyApplicationListener implements ApplicationListener<ApplicationStartedEvent> {// @Override // public void onApplicationEvent(ApplicationEvent event) { // System.out.println("事件觸發(fā):"+event.getClass().getName()); // }@Overridepublic void onApplicationEvent(ApplicationStartedEvent event) {System.out.println("事件觸發(fā):"+event.getClass().getName());}}可以看到控制臺(tái)輸出:這樣就觸發(fā)了spring默認(rèn)的一些事件。
事件觸發(fā):org.springframework.boot.context.event.ApplicationStartedEvent 事件觸發(fā):org.springframework.boot.context.event.ApplicationReadyEvent自定義事件以及監(jiān)聽(tīng)
 定義事件
 首先,我們需要定義一個(gè)時(shí)間(MyTestEvent),需要繼承Spring的ApplicationEvent
定義監(jiān)聽(tīng)器
 需要定義一下監(jiān)聽(tīng)器,自己定義的監(jiān)聽(tīng)器需要實(shí)現(xiàn)ApplicationListener,同時(shí)泛型參數(shù)要加上自己要監(jiān)聽(tīng)的事件Class名,在重寫的方法onApplicationEvent中,添加自己的業(yè)務(wù)處理:
事件發(fā)布
 有了事件,有了事件監(jiān)聽(tīng)者,那么什么時(shí)候觸發(fā)這個(gè)事件呢?每次想讓監(jiān)聽(tīng)器收到事件通知的時(shí)候,就可以調(diào)用一下事件發(fā)布的操作。首先在類里自動(dòng)注入了ApplicationEventPublisher,這個(gè)也就是我們的ApplicationCOntext,它實(shí)現(xiàn)了這個(gè)接口。
輸出結(jié)果如下圖所示:
非注解監(jiān)聽(tīng)器:我來(lái)了四:@EventListener 注解
 簡(jiǎn)單使用
 除了通過(guò)實(shí)現(xiàn)接口,還可以使用@EventListener 注解,實(shí)現(xiàn)對(duì)任意的方法都能監(jiān)聽(tīng)事件。
 在任意方法上標(biāo)注@EventListener 注解,指定 classes,即需要處理的事件類型,一般就是 ApplicationEven 及其子類,可以設(shè)置多項(xiàng)。
啟動(dòng)項(xiàng)目
 可以看到控制臺(tái)和之前的輸出是一樣的:
自定義事件以及監(jiān)聽(tīng)
 使用注解的好處是不用每次都去實(shí)現(xiàn)ApplicationListener,可以在一個(gè)class中定義多個(gè)方法,用@EventListener來(lái)做方法級(jí)別的注解。
 和上面類似,事件以及事件發(fā)布不需要改變,只要這樣定義監(jiān)聽(tīng)器即可。
此時(shí),就可以有一個(gè)發(fā)布,兩個(gè)監(jiān)聽(tīng)器監(jiān)聽(tīng)到發(fā)布的消息了,一個(gè)是注解方式,一個(gè)是非注解方式
 結(jié)果:
總結(jié)
 上面介紹了@EventListener的原理,其實(shí)上面方法里還有一個(gè)@TransactionalEventListener注解,其實(shí)原理是一模一樣的,只是這個(gè)監(jiān)聽(tīng)者可以選擇在事務(wù)完成后才會(huì)被執(zhí)行,事務(wù)執(zhí)行失敗就不會(huì)被執(zhí)行。
 這兩個(gè)注解的邏輯是一模一樣的,并且@TransactionalEventListener本身就被標(biāo)記有@EventListener,
 只是最后生成監(jiān)聽(tīng)器時(shí)所用的工廠不一樣而已。
?
創(chuàng)作挑戰(zhàn)賽新人創(chuàng)作獎(jiǎng)勵(lì)來(lái)咯,堅(jiān)持創(chuàng)作打卡瓜分現(xiàn)金大獎(jiǎng)總結(jié)
以上是生活随笔為你收集整理的SpringBoot中@EventListener注解的使用的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
                            
                        - 上一篇: @Async注解配合@EnableAsy
 - 下一篇: springboot activiti工