最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Spring?事件驅(qū)動(dòng)用法完整流程

 更新時(shí)間:2026年02月06日 11:02:57   作者:Vivienne_ChenW  
文章總結(jié)了Spring事件驅(qū)動(dòng)的完整流程,包括定義事件、發(fā)布事件、監(jiān)聽事件和線程池配置,本文結(jié)合實(shí)例代碼給大家介紹的非常詳細(xì),感興趣的朋友跟隨小編一起看看吧

一、Spring 事件驅(qū)動(dòng)完整流程總結(jié)

1. 定義事件:基類封裝 + 業(yè)務(wù)事件繼承

(1)事件基類:TestEvent(繼承 Spring 標(biāo)準(zhǔn) ApplicationEvent
作用:封裝通用事件數(shù)據(jù),作為所有相關(guān)事件的父類,減少重復(fù)代碼。
核心:繼承 ApplicationEvent,通過構(gòu)造器傳遞事件源(source) 和通用業(yè)務(wù)數(shù)據(jù)(cmd),并提供 getter 供子類 / 監(jiān)聽器獲取。

// 事件基類:封裝通用事件數(shù)據(jù)(可根據(jù)業(yè)務(wù)選擇是否需要通用事件封裝)
public class TestEvent extends ApplicationEvent {
    @Getter
    private CommonTestData cmd;
    // 構(gòu)造器:必傳事件源 + 通用業(yè)務(wù)數(shù)據(jù)
    public TestEvent(Object source, CommonTestData  cmd) {
        super(source); // 調(diào)用父類ApplicationEvent構(gòu)造器,綁定事件源
        this.cmd = cmd;
    }
}

(2)業(yè)務(wù)事件:RealTimeTestEvent(繼承 TestEvent)
作用:基于基類擴(kuò)展,定義具體業(yè)務(wù)場(chǎng)景的事件,無需重復(fù)封裝通用數(shù)據(jù)。
核心:直接復(fù)用父類 TestEvent 的構(gòu)造器,僅傳遞業(yè)務(wù)所需參數(shù),簡(jiǎn)化事件定義。

// 業(yè)務(wù)事件:繼承TestEvent,專注業(yè)務(wù)場(chǎng)景
public class RealTimeTestEvent extends TestEvent {
    // 直接復(fù)用父類構(gòu)造器,傳遞事件源 + 業(yè)務(wù)數(shù)據(jù)cmd
    public RealTimeTestEvent(Object source, CommonTestData cmd) {
        super(source, cmd);
    }
}

2. 發(fā)布事件:業(yè)務(wù)方法中觸發(fā)

注入 Spring 內(nèi)置 ApplicationEventPublisher,在核心業(yè)務(wù)邏輯完成后發(fā)布事件。
可通過開關(guān)(如 isTestEventTestEnable)控制是否發(fā)布,靈活適配業(yè)務(wù)需求。

@Autowired
private ApplicationEventPublisher eventPublisher;
// 業(yè)務(wù)方法中發(fā)布事件(核心邏輯執(zhí)行后)
if (isTestEventTestEnable) {
    // 構(gòu)造業(yè)務(wù)事件,傳遞事件源(this) + 業(yè)務(wù)數(shù)據(jù)md
    eventPublisher.publishEvent(new RealTimeTestEvent(this, md));
}

3. 監(jiān)聽事件:異步監(jiān)聽 + 自定義線程池

監(jiān)聽器類加 @Service(或 @Component),被 Spring 容器管理。
用 @EventListener 綁定具體事件,@Async 指定自定義線程池,實(shí)現(xiàn)異步非阻塞處理。
從事件中通過 getCmd() 獲取通用業(yè)務(wù)數(shù)據(jù),執(zhí)行附加邏輯。

@Slf4j
@Service
public class RealTimeTestEventListener {
    @SneakyThrows
    // 1. 指定自定義線程池,異步執(zhí)行(不阻塞主線程)
    @Async("RealTimeTestEventThreadPool")
    // 2. 監(jiān)聽RealTimeTestEvent事件(匹配事件類型)
    @EventListener(RealTimeTestEvent.class)
    public void handleEvent(RealTimeTestEvent event) {
        // 從事件基類TestEvent中獲取通用業(yè)務(wù)數(shù)據(jù)
        CommonTestData md = event.getCmd();
        // 執(zhí)行業(yè)務(wù)附加邏輯
        MktDataTestRealTimeListener.pushRealTimeTest(
            ...
        );
    }
}

4. 線程池配置:自定義隔離 + 動(dòng)態(tài)參數(shù)

用 @Configuration 聲明配置類,@Bean 定義線程池,供 @Async 調(diào)用。
從配置文件讀取線程池參數(shù)(核心數(shù)、最大數(shù)、隊(duì)列容量),支持動(dòng)態(tài)調(diào)整。
設(shè)置線程名前綴,方便日志排查;配置拒絕策略(如 CallerRunsPolicy)避免任務(wù)丟失。

@Configuration
public class TestEventThreadPool {
    @Autowired
    private ThreadPoolProperties threadPoolProperties;
    // 定義線程池Bean,指定名稱供@Async調(diào)用
    @Bean("realTimeTestEventThreadPool")
    public Executor realTimeTestEventThreadPool() {
        ThreadPoolTaskExecutor taskExecutor = new ThreadPoolTaskExecutor();
        // 動(dòng)態(tài)讀取配置參數(shù)
        taskExecutor.setCorePoolSize(threadPoolProperties.getRealTimeTest().getCoreSize());
        taskExecutor.setMaxPoolSize(threadPoolProperties.getRealTimeTest().getMaxPoolSize());
        taskExecutor.setQueueCapacity(threadPoolProperties.getRealTimeTest().getQueueCapacity());
        // 通用配置:線程名前綴、拒絕策略等
        taskExecutor.setThreadNamePrefix("realTimeTestEventThreadPool--");
        taskExecutor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
        // 初始化線程池
        taskExecutor.initialize();
        return taskExecutor;
    }
}

二、@EventListener vs @TransactionalEventListener:核心區(qū)別與適用場(chǎng)景

1. 核心區(qū)別(一句話總結(jié))

@EventListener:事件發(fā)布即執(zhí)行,不依賴事務(wù)狀態(tài);
@TransactionalEventListener:綁定事務(wù)階段執(zhí)行(如事務(wù)提交后),專為事務(wù)場(chǎng)景設(shè)計(jì)。

2.關(guān)鍵事務(wù)階段(phase)

@TransactionalEventListener 支持 4 種事務(wù)階段,按需選擇:
TransactionPhase.BEFORE_COMMIT:事務(wù)提交前執(zhí)行(慎用,可能阻塞事務(wù)提交);
TransactionPhase.AFTER_COMMIT:事務(wù)提交成功后執(zhí)行(最常用,保證數(shù)據(jù)一致性);
TransactionPhase.AFTER_ROLLBACK:事務(wù)回滾后執(zhí)行(如回滾補(bǔ)償邏輯);
TransactionPhase.AFTER_COMPLETION:事務(wù)完成后(無論提交 / 回滾)執(zhí)行。

3. 適用場(chǎng)景選型(結(jié)合你的業(yè)務(wù))

(1)用 @EventListener 的場(chǎng)景
業(yè)務(wù)無數(shù)據(jù)庫(kù)事務(wù),或事務(wù)與事件處理無數(shù)據(jù)依賴;不操作數(shù)據(jù)庫(kù),無數(shù)據(jù)一致性風(fēng)險(xiǎn),用 @EventListener 更簡(jiǎn)潔高效。
事件處理是輕量操作(如推送消息、記錄日志、更新緩存),無需等待事務(wù)提交;
(2)用 @TransactionalEventListener 的場(chǎng)景
事件處理依賴主事務(wù)的數(shù)據(jù)庫(kù)數(shù)據(jù)(如主事務(wù)更新數(shù)據(jù)后,監(jiān)聽器需讀取最新數(shù)據(jù));
需避免 “事務(wù)未提交,監(jiān)聽器讀取臟數(shù)據(jù)” 的問題;

三、整體核心價(jià)值總結(jié)

代碼復(fù)用:通過 TestEvent 基類封裝通用事件數(shù)據(jù),業(yè)務(wù)事件僅需繼承,減少重復(fù)代碼;
業(yè)務(wù)解耦:主業(yè)務(wù)只負(fù)責(zé)發(fā)布事件,監(jiān)聽器獨(dú)立處理附加邏輯,新增 / 刪除邏輯無需修改主業(yè)務(wù);
性能優(yōu)化:@Async + 自定義線程池,讓附加邏輯異步執(zhí)行,不阻塞主線程,提升接口響應(yīng)速度;
穩(wěn)定性保障:自定義線程池控制并發(fā),避免默認(rèn)線程池的 OOM 風(fēng)險(xiǎn);@TransactionalEventListener 解決事務(wù)場(chǎng)景的數(shù)據(jù)一致性問題;
靈活擴(kuò)展:支持多事件、多監(jiān)聽器、多線程池隔離,適配復(fù)雜業(yè)務(wù)場(chǎng)景。

四、快速選型口訣

非事務(wù)、輕量處理、無數(shù)據(jù)依賴 → 用 @EventListener;
事務(wù)場(chǎng)景、需讀最新事務(wù)數(shù)據(jù)、保證一致性 → 用 @TransactionalEventListener(phase = AFTER_COMMIT)。

五、Spring 事件驅(qū)動(dòng)和消息中間件選型

(1)、Spring 事件驅(qū)動(dòng):僅適用于同一個(gè)服務(wù)(進(jìn)程內(nèi)) 本地解耦
Spring 事件驅(qū)動(dòng)(ApplicationEvent/@EventListener/@TransactionalEventListener)的底層是基于 Spring 容器的內(nèi)存事件廣播機(jī)制,事件的發(fā)布、監(jiān)聽全程都在同一個(gè) JVM 進(jìn)程內(nèi)完成,無法跨服務(wù)、跨進(jìn)程、跨服務(wù)器傳遞。
核心價(jià)值:解決單服務(wù)內(nèi)部的業(yè)務(wù)解耦問題;
優(yōu)勢(shì):輕量、無中間件依賴、執(zhí)行效率高、無需考慮網(wǎng)絡(luò) / 序列化問題;
局限:僅單服務(wù)有效,服務(wù)集群部署時(shí),事件僅在當(dāng)前發(fā)布事件的服務(wù)實(shí)例中觸發(fā),其他實(shí)例無法感知。
(2)、跨服務(wù)解耦:必須使用消息中間件(主流選型)
當(dāng)需要跨服務(wù)、跨進(jìn)程、跨服務(wù)器傳遞事件 / 消息時(shí),Spring 事件驅(qū)動(dòng)完全無法滿足,此時(shí)消息中間件(MQ) 是標(biāo)準(zhǔn)且唯一的解決方案,其核心作用是實(shí)現(xiàn)分布式系統(tǒng)中的異步通信與解耦。
主流消息中間件選型(按場(chǎng)景適配):
RabbitMQ:基于 AMQP 協(xié)議,支持豐富的消息路由(直連、主題、扇出等)、消息確認(rèn)、死信隊(duì)列,適配復(fù)雜的業(yè)務(wù)場(chǎng)景(如訂單支付后跨服務(wù)通知庫(kù)存、物流),企業(yè)級(jí)項(xiàng)目首選;
Kafka:基于發(fā)布 - 訂閱模式,高吞吐、低延遲、高可用,適合大數(shù)據(jù)量、高并發(fā)的日志收集、實(shí)時(shí)數(shù)據(jù)同步、流處理場(chǎng)景;
RocketMQ:阿里開源,兼顧 RabbitMQ 的功能豐富性和 Kafka 的高吞吐,支持分布式事務(wù)消息,適合電商、金融等核心業(yè)務(wù)場(chǎng)景;
ActiveMQ:老牌消息中間件,協(xié)議支持全面,但性能和高可用略遜于前三者,適合中小型項(xiàng)目或傳統(tǒng)項(xiàng)目。

到此這篇關(guān)于Spring 事件驅(qū)動(dòng)用法完整流程的文章就介紹到這了,更多相關(guān)Spring 事件驅(qū)動(dòng)用法內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • java8中的默認(rèn)垃圾回收器(GC)

    java8中的默認(rèn)垃圾回收器(GC)

    這篇文章主要介紹了java8中的默認(rèn)垃圾回收器(GC),具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-05-05
  • 基于Java實(shí)現(xiàn)簡(jiǎn)單貪吃蛇游戲

    基于Java實(shí)現(xiàn)簡(jiǎn)單貪吃蛇游戲

    這篇文章主要為大家詳細(xì)介紹了基于Java實(shí)現(xiàn)簡(jiǎn)單貪吃蛇,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-04-04
  • springboot使用kafka事務(wù)的示例代碼

    springboot使用kafka事務(wù)的示例代碼

    Kafka?同數(shù)據(jù)庫(kù)一樣支持事務(wù),當(dāng)發(fā)生異常的時(shí)候可以進(jìn)行回滾,確保消息監(jiān)聽器不會(huì)接收到一些錯(cuò)誤的或者不需要的消息,本文就來介紹一下springboot使用kafka事務(wù)的示例代碼,具有一定的參考價(jià)值,感興趣的可以了解一下
    2024-06-06
  • 深入學(xué)習(xí)Hibernate持久化對(duì)象的三個(gè)狀態(tài)

    深入學(xué)習(xí)Hibernate持久化對(duì)象的三個(gè)狀態(tài)

    Hibernate中的對(duì)象有3中狀態(tài),瞬時(shí)對(duì)象(TransientObjects)、持久化對(duì)象(PersistentObjects)和離線對(duì)象(DetachedObjects也叫做脫管對(duì)象),下面通過本文給大家分享Hibernate持久化對(duì)象的三個(gè)狀態(tài),一起看看吧
    2017-09-09
  • java時(shí)間和字符串之間相互轉(zhuǎn)換幾種方法

    java時(shí)間和字符串之間相互轉(zhuǎn)換幾種方法

    這篇文章主要介紹了java時(shí)間和字符串之間相互轉(zhuǎn)換的幾種方法,還詳細(xì)解釋了DateTimeFormatter的三種解析模式,并比較了yyyy和uuuu在嚴(yán)格模式下的區(qū)別,需要的朋友可以參考下
    2025-03-03
  • IDEA安裝Activiti插件并解決亂碼問題(推薦)

    IDEA安裝Activiti插件并解決亂碼問題(推薦)

    這篇文章主要介紹了IDEA安裝Activiti插件并解決亂碼問題,本文通過圖文并茂的形式給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2020-06-06
  • mybatis動(dòng)態(tài)新增(insert)和修改(update)方式

    mybatis動(dòng)態(tài)新增(insert)和修改(update)方式

    這篇文章主要介紹了mybatis動(dòng)態(tài)新增(insert)和修改(update)方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2024-05-05
  • Java序列化框架Kryo高效轉(zhuǎn)換對(duì)象為字節(jié)流面試精講

    Java序列化框架Kryo高效轉(zhuǎn)換對(duì)象為字節(jié)流面試精講

    這篇文章主要為大家介紹了Java序列化框架Kryo高效轉(zhuǎn)換對(duì)象為字節(jié)流面試精講,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-10-10
  • Java 深入淺出掌握Collection單列集合Set

    Java 深入淺出掌握Collection單列集合Set

    Collection集合類是單列集合類的根接口,用來存儲(chǔ)一系列符合某種規(guī)則的元素。List接口和Set接口是Collection集合類的子接口,其中List接口的常用實(shí)現(xiàn)類有ArrayList類、Vector類和LinkedList類;Set接口的常用實(shí)現(xiàn)類有HashSet類和TreeSet類
    2021-11-11
  • 詳解SpringMVC和MyBatis框架開發(fā)環(huán)境搭建和簡(jiǎn)單實(shí)用

    詳解SpringMVC和MyBatis框架開發(fā)環(huán)境搭建和簡(jiǎn)單實(shí)用

    這篇文章主要介紹了詳解SpringMVC和MyBatis框架開發(fā)環(huán)境搭建和簡(jiǎn)單實(shí)用,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-05-05

最新評(píng)論

宣恩县| 金平| 左贡县| 大丰市| 峨眉山市| 吴堡县| 原阳县| 讷河市| 华宁县| 新晃| 专栏| 松桃| 贡山| 泾川县| 化隆| 灵武市| 镇坪县| 察隅县| 仁寿县| 毕节市| 井冈山市| 绥德县| 武冈市| 大石桥市| 太仓市| 阿勒泰市| 龙南县| 克山县| 蓝田县| 三亚市| 北辰区| 许昌市| 潼关县| 庆元县| 措美县| 汾阳市| 改则县| 左云县| 株洲市| 郁南县| 龙里县|