spring @EventListener 事件與監(jiān)聽的示例詳解
1、自定義Application Event
package com.ybw.event.pojo; import lombok.Getter; import lombok.Setter; import org.springframework.context.ApplicationEvent; /** * @className MyEvent * @author weixiansheng * @date 2023/9/28 * @version V1.0 **/ @Setter @Getter public class MyEvent extends ApplicationEvent { private String data; public MyEvent(Object source, String data) { super(source); this.data = data; } }
2、自定義監(jiān)聽
package com.ybw.event.listener; import com.ybw.event.pojo.MyEvent; import lombok.extern.slf4j.Slf4j; import org.springframework.context.event.EventListener; import org.springframework.stereotype.Component; /** * 簡單監(jiān)聽 * * @author weixiansheng * @version V1.0 * @className MySimpleListener * @date 2023/9/28 **/ @Component @Slf4j public class MySimpleListener { /** * @param event * @methodName: handleDemoEvent * @return: void * @author: weixiansheng * @date: 2023/9/28 **/ @EventListener public void handleDemoEvent(MyEvent event) { log.info("發(fā)布的data為:{}", event.getData()); } }
3、測試
package com.ybw.event.listener; import com.ybw.event.pojo.MyEvent; import com.ybw.util.SpringContextHolder; import lombok.extern.slf4j.Slf4j; import org.junit.jupiter.api.Test; import org.springframework.boot.test.context.SpringBootTest; import java.util.concurrent.TimeUnit; /** * @author weixiansheng * @version V1.0 * @className MySimpleListenerTest * @date 2023/9/28 **/ @SpringBootTest @Slf4j class MySimpleListenerTest { /** * 發(fā)布消息 * * @methodName: publishEvent * @return: void * @author: weixiansheng * @date: 2023/9/28 **/ @Test public void publishEvent() throws InterruptedException { log.info("publishEvent start"); SpringContextHolder.publishEvent(new MyEvent(this, "測試")); log.info("publishEvent end"); TimeUnit.DAYS.sleep(1); } }
打印日志
[INFO ] 2023-09-28 10:19:15.312 [main] c.y.e.listener.MySimpleListenerTest - publishEvent start
[INFO ] 2023-09-28 10:19:16.344 [main] c.y.event.listener.MySimpleListener - 發(fā)布的data為:測試
[INFO ] 2023-09-28 10:19:16.347 [main] c.y.e.listener.MySimpleListenerTest - publishEvent end
4、源代碼
5、其他
5.1 順序執(zhí)行
使用注解
- @Order order的值越小,優(yōu)先級越高。
- order如果不標(biāo)注數(shù)字,默認(rèn)最低優(yōu)先級,因?yàn)槠淠J(rèn)值是int最大值。
示例
/** * 普通監(jiān)聽 * * @param event * @methodName: handleDemoEvent * @return: void * @author: weixiansheng * @date: 2023/9/28 **/ @EventListener @Order(2) public void handleEvent(MyEvent event) throws InterruptedException { TimeUnit.SECONDS.sleep(1); log.info("handleEvent data:{}", event.getData()); } /** * 條件監(jiān)聽 * * @param event * @methodName: handleConditionEvent * @return: void * @author: weixiansheng * @date: 2023/9/28 **/ @EventListener(condition = "#event.data=='張三'") @Order(1) public void handleConditionEvent(MyEvent event) { log.info("handleConditionEvent data:{}", event.getData()); }
打印日志
[INFO ] 2023-09-28 10:40:22.206 [main] c.y.event.listener.MySimpleListener - handleConditionEvent data:張三
[INFO ] 2023-09-28 10:40:23.216 [main] c.y.event.listener.MySimpleListener - handleEvent data:張三
5.2 異步支持
Spring 事件機(jī)制默認(rèn)是同步阻塞的,如果 ApplicationEventPublisher 發(fā)布事件之后他會一直阻塞等待listener 響應(yīng),多個 listener 的情況下前面的沒有執(zhí)行完后面的會一直被阻塞。發(fā)布者和訂閱者屬于同一事務(wù),如果訂閱者執(zhí)行失敗了,發(fā)布者事務(wù)會回滾。
可以利用 Spring 提供的線程池注解 @Async 來實(shí)現(xiàn)異步線程。異步不影響發(fā)布者的事務(wù)。
示例
/** * 普通監(jiān)聽 * * @param event * @methodName: handleDemoEvent * @return: void * @author: weixiansheng * @date: 2023/9/28 **/ @EventListener public void handleEvent(MyEvent event) throws InterruptedException { TimeUnit.SECONDS.sleep(1); log.info("handleEvent data:{}", event.getData()); } /** * 條件監(jiān)聽 * * @param event * @methodName: handleConditionEvent * @return: void * @author: weixiansheng * @date: 2023/9/28 **/ @Async @EventListener(condition = "#event.data=='張三'") public void handleConditionEvent(MyEvent event) { log.info("handleConditionEvent data:{}", event.getData()); }
打印日志
[INFO ] 2023-09-28 10:49:40.246 [thread-pool-1] com.ybw.event.listener.MyListener - handleConditionEvent data:張三
[INFO ] 2023-09-28 10:49:41.255 [main] com.ybw.event.listener.MyListener - handleEvent data:張三
一個是線程thread-pool-1,一個是線程main。
6、總結(jié)
- 事件模式概念
- 事件:事件的觸發(fā)者,比如用戶注冊就是事件。
- 事件發(fā)布:描述發(fā)生了什么事情的對象,比如張三注冊成功的事件。
- 事件監(jiān)聽:監(jiān)聽到事件發(fā)生的時候,做一些處理,比如下單后,增加用戶積分。
- Spring中事件監(jiān)聽器的處理是同步方式
- 日志都是都一個線程。
- 執(zhí)行時順序的,執(zhí)行完監(jiān)聽器的業(yè)務(wù)后,會向下繼續(xù)執(zhí)行后面的邏輯。如上例:publishEvent end。
到此這篇關(guān)于spring @EventListener 事件與監(jiān)聽的文章就介紹到這了,更多相關(guān)spring @EventListener 事件與監(jiān)聽內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Spring Security實(shí)現(xiàn)5次密碼錯誤觸發(fā)賬號自動鎖定功能
在現(xiàn)代互聯(lián)網(wǎng)應(yīng)用中,賬號安全是重中之重,然而,暴力 破解攻擊依然是最常見的安全威脅之一,攻擊者通過自動化腳本嘗試大量的用戶名和密碼組合,試圖找到漏洞進(jìn)入系統(tǒng),所以為了解決這一問題,賬號鎖定機(jī)制被廣泛應(yīng)用,本文介紹了Spring Security實(shí)現(xiàn)5次密碼錯誤觸發(fā)賬號鎖定功能2024-12-12Windows中使用Java生成Excel文件并插入圖片的方法
這篇文章主要介紹了Windows中使用Java生成Excel文件并插入圖片的方法,其中向Excel中插入圖片文中通過使用Apache POI來實(shí)現(xiàn),需要的朋友可以參考下2016-02-02Java實(shí)現(xiàn)給圖片添加圖片水印,文字水印及馬賽克的方法示例
這篇文章主要介紹了Java實(shí)現(xiàn)給圖片添加圖片水印,文字水印及馬賽克的方法,涉及java針對圖片的讀取、水印添加、馬賽克設(shè)置等相關(guān)操作技巧,需要的朋友可以參考下2018-01-01Spring-cloud-eureka使用feign調(diào)用服務(wù)接口
這篇文章主要為大家詳細(xì)介紹了Spring-cloud-eureka使用feign調(diào)用服務(wù)接口,具有一定的參考價值,感興趣的小伙伴們可以參考一下2019-04-04Maven腳手架如何基于jeecg實(shí)現(xiàn)快速開發(fā)
這篇文章主要介紹了Maven腳手架如何基于jeecg實(shí)現(xiàn)快速開發(fā),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下2020-10-10java并發(fā)編程工具類JUC之LinkedBlockingQueue鏈表隊(duì)列
大家都知道LinkedBlockingQueue 隊(duì)列是BlockingQueue接口的實(shí)現(xiàn)類,所以它具有BlockingQueue接口的一切功能特點(diǎn),他還提供了兩種構(gòu)造函數(shù),本文中通過實(shí)例代碼給大家介紹的非常詳細(xì),需要的朋友參考下吧2021-06-06