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

Java Spring ApplicationEvent 代碼示例解析

 更新時(shí)間:2025年06月17日 17:10:38   作者:兔子蟹子  
本文解析了Spring事件機(jī)制,涵蓋核心概念(發(fā)布-訂閱/觀察者模式)、代碼實(shí)現(xiàn)(事件定義、發(fā)布、監(jiān)聽(tīng))及高級(jí)應(yīng)用(異步處理、事務(wù)綁定、執(zhí)行順序),對(duì)Java Spring ApplicationEvent概念相關(guān)知識(shí)感興趣的朋友一起看看吧

一、Spring 事件機(jī)制核心概念

1. 事件驅(qū)動(dòng)架構(gòu)模型

  • 發(fā)布-訂閱模式:解耦事件生產(chǎn)者和消費(fèi)者
  • 觀察者模式:監(jiān)聽(tīng)器監(jiān)聽(tīng)特定事件
  • 事件驅(qū)動(dòng)優(yōu)勢(shì)
    • 組件間松耦合
    • 系統(tǒng)擴(kuò)展性好
    • 支持異步處理
    • 事件溯源支持

2. 核心組件

組件作用實(shí)現(xiàn)方式
ApplicationEvent事件基類自定義事件需繼承
ApplicationEventPublisher事件發(fā)布接口通過(guò)Spring容器注入
ApplicationListener事件監(jiān)聽(tīng)接口實(shí)現(xiàn)接口或使用@EventListener

二、代碼示例解析

1. 事件定義 (KnowledgeService.java)

@Getter
public static final class ImportedKnowledgeEvent extends ApplicationEvent {
    private final Knowledge knowledge;
    private final KWDocument document;
    // 構(gòu)造器1:只有knowledge
    public ImportedKnowledgeEvent(Object source, Knowledge knowledge) {
        super(source);
        this.knowledge = knowledge;
        this.document = null;
    }
    // 構(gòu)造器2:knowledge + document
    public ImportedKnowledgeEvent(Object source, Knowledge knowledge, KWDocument document) {
        super(source);
        this.knowledge = knowledge;
        this.document = document;
    }
}

關(guān)鍵點(diǎn)

  • 繼承ApplicationEvent基類
  • 使用final字段保證事件不可變性
  • 提供多種構(gòu)造器支持不同場(chǎng)景
  • 使用@Getter(Lombok)提供訪問(wèn)方法

2. 事件發(fā)布 (KnowledgeService.java)

@Service
public class KnowledgeService {
    @Autowired
    protected ApplicationEventPublisher eventPublisher;
    public void imports() {
        // 發(fā)布簡(jiǎn)單知識(shí)導(dǎo)入事件
        eventPublisher.publishEvent(new ImportedKnowledgeEvent(this, new Knowledge()));
        // 發(fā)布知識(shí)+文檔導(dǎo)入事件
        eventPublisher.publishEvent(new ImportedKnowledgeEvent(this, new Knowledge(), new KWDocument()));
    }
}

發(fā)布模式

  • 注入ApplicationEventPublisher
  • 創(chuàng)建事件對(duì)象(包含業(yè)務(wù)數(shù)據(jù))
  • 調(diào)用publishEvent()發(fā)布
  • 支持多種事件類型重載

3. 事件監(jiān)聽(tīng) (KnowledgeRagflowService.java)

@Service
public class KnowledgeRagflowService extends KnowledgeService {
    @EventListener
    public void importedKnowledge(KnowledgeService.ImportedKnowledgeEvent event) {
        if (event.getDocument() != null) {
            dealDocument(event.getKnowledge(), event.getDocument());
        } else {
            dealKnowledge(event.getKnowledge());
        }
    }
    private void dealDocument(Knowledge knowledge, Document document) {
        // 處理文檔邏輯
    }
    private void dealKnowledge(Knowledge knowledge) {
        // 處理知識(shí)邏輯
    }
}

監(jiān)聽(tīng)器特點(diǎn)

  • 使用@EventListener注解簡(jiǎn)化實(shí)現(xiàn)
  • 方法參數(shù)決定監(jiān)聽(tīng)的事件類型
  • 支持事件內(nèi)容判斷(區(qū)分有無(wú)document)
  • 私有方法封裝具體處理邏輯

三、高級(jí)應(yīng)用技巧

1. 條件監(jiān)聽(tīng)

@EventListener(condition = "#event.document != null")
public void handleDocumentEvent(ImportedKnowledgeEvent event) {
    // 僅處理包含document的事件
}

2. 異步事件處理

@Async
@EventListener
public void asyncHandleEvent(ImportedKnowledgeEvent event) {
    // 異步處理耗時(shí)操作
}

配置要求

  • 主類添加@EnableAsync
  • 配置線程池:
@Configuration
@EnableAsync
public class AsyncConfig implements AsyncConfigurer {
    @Override
    public Executor getAsyncExecutor() {
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        executor.setCorePoolSize(5);
        executor.setMaxPoolSize(10);
        executor.setQueueCapacity(25);
        executor.initialize();
        return executor;
    }
}

3. 監(jiān)聽(tīng)器執(zhí)行順序

@Order(1)
@EventListener
public void firstListener(ImportedKnowledgeEvent event) {
    // 最先執(zhí)行
}
@Order(2)
@EventListener
public void secondListener(ImportedKnowledgeEvent event) {
    // 其次執(zhí)行
}

4. 事務(wù)綁定事件

@TransactionalEventListener(phase = TransactionPhase.AFTER_COMMIT)
public void afterCommitEvent(ImportedKnowledgeEvent event) {
    // 事務(wù)提交后執(zhí)行
}

事務(wù)階段選項(xiàng)

  • AFTER_COMMIT(默認(rèn)):事務(wù)成功提交后
  • AFTER_ROLLBACK:事務(wù)回滾后
  • AFTER_COMPLETION:事務(wù)完成后(提交或回滾)
  • BEFORE_COMMIT:事務(wù)提交前

四、最佳實(shí)踐

1. 事件設(shè)計(jì)原則

  • 單一職責(zé):一個(gè)事件只攜帶一種業(yè)務(wù)變更
  • 不可變性:事件發(fā)布后內(nèi)容不可修改
  • 上下文完整:包含所有必要業(yè)務(wù)數(shù)據(jù)
  • 命名規(guī)范:使用過(guò)去時(shí)態(tài)(如ImportedKnowledgeEvent

2. 性能優(yōu)化

  • 同步/異步選擇

  • 批量處理:對(duì)高頻事件進(jìn)行批量合并
  • 事件過(guò)濾:在監(jiān)聽(tīng)器內(nèi)部添加條件判斷

3. 錯(cuò)誤處理

@EventListener
public void handleEvent(ImportedKnowledgeEvent event) {
    try {
        // 業(yè)務(wù)處理
    } catch (Exception e) {
        // 1. 記錄錯(cuò)誤日志
        // 2. 發(fā)布錯(cuò)誤處理事件
        // 3. 重試機(jī)制(如Spring Retry)
    }
}

4. 測(cè)試策略

@SpringBootTest
class KnowledgeEventTest {
    @Autowired
    private ApplicationEventPublisher eventPublisher;
    @MockBean
    private KnowledgeRagflowService ragflowService;
    @Test
    void shouldTriggerListenerWhenPublishEvent() {
        // 準(zhǔn)備測(cè)試事件
        ImportedKnowledgeEvent event = new ImportedKnowledgeEvent(this, new Knowledge());
        // 發(fā)布事件
        eventPublisher.publishEvent(event);
        // 驗(yàn)證監(jiān)聽(tīng)器調(diào)用
        verify(ragflowService, timeout(1000)).importedKnowledge(event);
    }
}

五、典型應(yīng)用場(chǎng)景

  • 業(yè)務(wù)狀態(tài)變更通知

    • 知識(shí)導(dǎo)入完成通知
    • 文檔處理狀態(tài)更新
  • 跨模塊協(xié)作

    • 知識(shí)導(dǎo)入后觸發(fā)索引更新
    • 文檔處理完成后通知搜索服務(wù)

系統(tǒng)生命周期事件

@EventListener
public void onApplicationReady(ContextRefreshedEvent event) {
    // 應(yīng)用啟動(dòng)完成后初始化資源
}

審計(jì)日志記錄

@EventListener
public void auditLog(ImportedKnowledgeEvent event) {
    log.info("Knowledge imported: {}", event.getKnowledge().getId());
}
  • 業(yè)務(wù)流程編排

六、常見(jiàn)問(wèn)題解決方案

  • 監(jiān)聽(tīng)器未觸發(fā)

    • 檢查事件類型是否匹配
    • 確認(rèn)監(jiān)聽(tīng)器在Spring容器中
    • 驗(yàn)證事件是否成功發(fā)布

循環(huán)事件觸發(fā)

// 使用標(biāo)記防止循環(huán)
public void imports() {
    if (!EventContext.isEventProcessing()) {
        eventPublisher.publishEvent(...);
    }
}
  • 事件數(shù)據(jù)過(guò)大

    • 改為傳遞引用ID而非整個(gè)對(duì)象
    • 使用DTO精簡(jiǎn)數(shù)據(jù)
    • 添加@Lazy注解延遲加載
  • 監(jiān)聽(tīng)器執(zhí)行順序問(wèn)題

    • 使用@Order明確順序
    • 拆分事件避免依賴

總結(jié)

Spring ApplicationEvent 提供了強(qiáng)大的事件驅(qū)動(dòng)編程模型,通過(guò)示例中的KnowledgeServiceKnowledgeRagflowService展示了:

  • 如何定義包含業(yè)務(wù)數(shù)據(jù)的事件
  • 多種事件發(fā)布方式
  • 使用@EventListener簡(jiǎn)化監(jiān)聽(tīng)器實(shí)現(xiàn)
  • 根據(jù)事件內(nèi)容執(zhí)行不同處理邏輯

在實(shí)際應(yīng)用中,應(yīng)結(jié)合:

  • 異步處理提升性能
  • 事務(wù)綁定確保數(shù)據(jù)一致性
  • 條件過(guò)濾優(yōu)化事件處理
  • 完善錯(cuò)誤處理機(jī)制

遵循"高內(nèi)聚、低耦合"原則,合理使用事件驅(qū)動(dòng)架構(gòu),可以顯著提升系統(tǒng)的擴(kuò)展性和可維護(hù)性。

到此這篇關(guān)于Java Spring ApplicationEvent 代碼示例解析的文章就介紹到這了,更多相關(guān)Spring ApplicationEvent 內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Spring?boot框架JWT實(shí)現(xiàn)用戶賬戶密碼登錄驗(yàn)證流程

    Spring?boot框架JWT實(shí)現(xiàn)用戶賬戶密碼登錄驗(yàn)證流程

    這篇文章主要介紹了Springboot框架JWT實(shí)現(xiàn)用戶賬戶密碼登錄驗(yàn)證,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2023-06-06
  • 使用Java進(jìn)行Json數(shù)據(jù)的解析(對(duì)象數(shù)組的相互嵌套)

    使用Java進(jìn)行Json數(shù)據(jù)的解析(對(duì)象數(shù)組的相互嵌套)

    下面小編就為大家?guī)?lái)一篇使用Java進(jìn)行Json數(shù)據(jù)的解析(對(duì)象數(shù)組的相互嵌套)。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2017-08-08
  • 淺談Java ThreadPoolExecutor的使用

    淺談Java ThreadPoolExecutor的使用

    今天我們來(lái)學(xué)習(xí)一下Java ThreadPoolExecutor的使用,文中有非常詳細(xì)的介紹及代碼示例,對(duì)正在學(xué)習(xí)Java的小伙伴們有很大的幫助,需要的朋友可以參考下
    2021-05-05
  • java中線程池最實(shí)用的創(chuàng)建與關(guān)閉指南

    java中線程池最實(shí)用的創(chuàng)建與關(guān)閉指南

    試中經(jīng)常會(huì)問(wèn)到,創(chuàng)建一個(gè)線程池需要哪些參數(shù)啊,線程池的工作原理啊,卻很少會(huì)問(wèn)到線程池如何安全關(guān)閉的,下面這篇文章主要給大家介紹了關(guān)于java中線程池最實(shí)用的創(chuàng)建與關(guān)閉的相關(guān)資料,需要的朋友可以參考下
    2021-09-09
  • IDEA如何進(jìn)行commit之后的代碼回退

    IDEA如何進(jìn)行commit之后的代碼回退

    在 IntelliJ IDEA 中回退 Git 版本涉及查找提交記錄、復(fù)制提交編號(hào)、重置 HEAD 并強(qiáng)行推送到遠(yuǎn)程倉(cāng)庫(kù),本文提供詳細(xì)步驟和注意事項(xiàng),幫助用戶安全地回退到舊版本
    2024-09-09
  • Spring?Boot?實(shí)現(xiàn)?WebSocket?的代碼示例

    Spring?Boot?實(shí)現(xiàn)?WebSocket?的代碼示例

    WebSocket?協(xié)議是獨(dú)立的基于?TCP?協(xié)議。它與?HTTP?的唯一關(guān)系是,它的握手會(huì)被?HTTP?服務(wù)器解釋為?Upgrade?請(qǐng)求,接下來(lái)通過(guò)本文給大家介紹Spring?Boot?實(shí)現(xiàn)?WebSocket?示例詳解,需要的朋友可以參考下
    2022-04-04
  • java實(shí)現(xiàn)學(xué)生教師管理系統(tǒng)

    java實(shí)現(xiàn)學(xué)生教師管理系統(tǒng)

    這篇文章主要為大家詳細(xì)介紹了java實(shí)現(xiàn)學(xué)生教師管理系統(tǒng),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2020-10-10
  • 在Spring 中使用@Aspect 控制自定義注解的操作

    在Spring 中使用@Aspect 控制自定義注解的操作

    這篇文章主要介紹了在Spring 中使用@Aspect 控制自定義注解的操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2021-01-01
  • Java 動(dòng)態(tài)模擬操作系統(tǒng)進(jìn)程調(diào)度算法

    Java 動(dòng)態(tài)模擬操作系統(tǒng)進(jìn)程調(diào)度算法

    這篇文章主要介紹了采用java語(yǔ)言編程模擬N個(gè)進(jìn)程采用動(dòng)態(tài)高優(yōu)先權(quán)優(yōu)先進(jìn)程調(diào)度算法。文中代碼具有一定的學(xué)習(xí)價(jià)值,感興趣的小伙伴可以了解一下
    2021-12-12
  • Java并發(fā)編程-volatile可見(jiàn)性詳解

    Java并發(fā)編程-volatile可見(jiàn)性詳解

    這篇文章主要介紹了Java并發(fā)編程-volatile可見(jiàn)性詳解,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2019-03-03

最新評(píng)論

苗栗市| 定安县| 南澳县| 望城县| 科尔| 常山县| 仁化县| 蒲城县| 游戏| 无锡市| 闽侯县| 通海县| 盐亭县| 宣汉县| 伊宁县| 许昌县| 略阳县| 德格县| 遵义市| 邵阳县| 雅江县| 崇义县| 梨树县| 泸溪县| 九江市| 平南县| 新昌县| 陵川县| 临夏县| 吴堡县| 华容县| 巴彦县| 昌图县| 乐山市| 额济纳旗| 香港 | 泌阳县| 马尔康县| 惠来县| 临颍县| 留坝县|