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-12
Windows中使用Java生成Excel文件并插入圖片的方法
這篇文章主要介紹了Windows中使用Java生成Excel文件并插入圖片的方法,其中向Excel中插入圖片文中通過使用Apache POI來實(shí)現(xiàn),需要的朋友可以參考下2016-02-02
Java實(shí)現(xiàn)給圖片添加圖片水印,文字水印及馬賽克的方法示例
這篇文章主要介紹了Java實(shí)現(xiàn)給圖片添加圖片水印,文字水印及馬賽克的方法,涉及java針對圖片的讀取、水印添加、馬賽克設(shè)置等相關(guān)操作技巧,需要的朋友可以參考下2018-01-01
Spring-cloud-eureka使用feign調(diào)用服務(wù)接口
這篇文章主要為大家詳細(xì)介紹了Spring-cloud-eureka使用feign調(diào)用服務(wù)接口,具有一定的參考價值,感興趣的小伙伴們可以參考一下2019-04-04
Maven腳手架如何基于jeecg實(shí)現(xiàn)快速開發(fā)
這篇文章主要介紹了Maven腳手架如何基于jeecg實(shí)現(xiàn)快速開發(fā),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下2020-10-10
java并發(fā)編程工具類JUC之LinkedBlockingQueue鏈表隊(duì)列
大家都知道LinkedBlockingQueue 隊(duì)列是BlockingQueue接口的實(shí)現(xiàn)類,所以它具有BlockingQueue接口的一切功能特點(diǎn),他還提供了兩種構(gòu)造函數(shù),本文中通過實(shí)例代碼給大家介紹的非常詳細(xì),需要的朋友參考下吧2021-06-06

