Java Spring ApplicationEvent 概述

一、Spring 事件機制核心概念

1. 事件驅動架構模型

  • 發布-訂閱模式:解耦事件生產者和消費者
  • 觀察者模式:監聽器監聽特定事件
  • 事件驅動優勢
    • 組件間松耦合
    • 系統擴展性好
    • 支持異步處理
    • 事件溯源支持

2. 核心組件

組件作用實現方式
ApplicationEvent事件基類自定義事件需繼承
ApplicationEventPublisher事件發布接口通過Spring容器注入
ApplicationListener事件監聽接口實現接口或使用@EventListener

二、代碼示例解析

1. 事件定義 (KnowledgeService.java)

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

關鍵點

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

2. 事件發布 (KnowledgeService.java)

@Service
public class KnowledgeService {@Autowiredprotected ApplicationEventPublisher eventPublisher;public void imports() {// 發布簡單知識導入事件eventPublisher.publishEvent(new ImportedKnowledgeEvent(this, new Knowledge()));// 發布知識+文檔導入事件eventPublisher.publishEvent(new ImportedKnowledgeEvent(this, new Knowledge(), new KWDocument()));}
}

發布模式

  1. 注入ApplicationEventPublisher
  2. 創建事件對象(包含業務數據)
  3. 調用publishEvent()發布
  4. 支持多種事件類型重載

3. 事件監聽 (KnowledgeRagflowService.java)

@Service
public class KnowledgeRagflowService extends KnowledgeService {@EventListenerpublic 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) {// 處理知識邏輯}
}

監聽器特點

  • 使用@EventListener注解簡化實現
  • 方法參數決定監聽的事件類型
  • 支持事件內容判斷(區分有無document)
  • 私有方法封裝具體處理邏輯

三、高級應用技巧

1. 條件監聽

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

2. 異步事件處理

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

配置要求

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

3. 監聽器執行順序

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

4. 事務綁定事件

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

事務階段選項

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

四、最佳實踐

1. 事件設計原則

  • 單一職責:一個事件只攜帶一種業務變更
  • 不可變性:事件發布后內容不可修改
  • 上下文完整:包含所有必要業務數據
  • 命名規范:使用過去時態(如ImportedKnowledgeEvent

2. 性能優化

  • 同步/異步選擇
    事件發布
    是否耗時?
    異步處理
    同步處理
  • 批量處理:對高頻事件進行批量合并
  • 事件過濾:在監聽器內部添加條件判斷

3. 錯誤處理

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

4. 測試策略

@SpringBootTest
class KnowledgeEventTest {@Autowiredprivate ApplicationEventPublisher eventPublisher;@MockBeanprivate KnowledgeRagflowService ragflowService;@Testvoid shouldTriggerListenerWhenPublishEvent() {// 準備測試事件ImportedKnowledgeEvent event = new ImportedKnowledgeEvent(this, new Knowledge());// 發布事件eventPublisher.publishEvent(event);// 驗證監聽器調用verify(ragflowService, timeout(1000)).importedKnowledge(event);}
}

五、典型應用場景

  1. 業務狀態變更通知

    • 知識導入完成通知
    • 文檔處理狀態更新
  2. 跨模塊協作

    • 知識導入后觸發索引更新
    • 文檔處理完成后通知搜索服務
  3. 系統生命周期事件

    @EventListener
    public void onApplicationReady(ContextRefreshedEvent event) {// 應用啟動完成后初始化資源
    }
    
  4. 審計日志記錄

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

    ImportService EventBus IndexService NotificationService 發布ImportedKnowledgeEvent 觸發索引更新 觸發通知發送 ImportService EventBus IndexService NotificationService

六、常見問題解決方案

  1. 監聽器未觸發

    • 檢查事件類型是否匹配
    • 確認監聽器在Spring容器中
    • 驗證事件是否成功發布
  2. 循環事件觸發

    // 使用標記防止循環
    public void imports() {if (!EventContext.isEventProcessing()) {eventPublisher.publishEvent(...);}
    }
    
  3. 事件數據過大

    • 改為傳遞引用ID而非整個對象
    • 使用DTO精簡數據
    • 添加@Lazy注解延遲加載
  4. 監聽器執行順序問題

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

總結

Spring ApplicationEvent 提供了強大的事件驅動編程模型,通過示例中的KnowledgeServiceKnowledgeRagflowService展示了:

  • 如何定義包含業務數據的事件
  • 多種事件發布方式
  • 使用@EventListener簡化監聽器實現
  • 根據事件內容執行不同處理邏輯

在實際應用中,應結合:

  1. 異步處理提升性能
  2. 事務綁定確保數據一致性
  3. 條件過濾優化事件處理
  4. 完善錯誤處理機制

遵循"高內聚、低耦合"原則,合理使用事件驅動架構,可以顯著提升系統的擴展性和可維護性。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/diannao/86954.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/86954.shtml
英文地址,請注明出處:http://en.pswp.cn/diannao/86954.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Spring核心框架完全指南 - 基礎知識全解析

?? 目錄 ?? Spring框架簡介 ??? IoC容器詳解 ?? 依賴注入(DI)深入理解 ?? Bean配置與管理 ?? Bean的作用域 ?? Bean生命周期 ?? 面向切面編程(AOP) ?? Spring注解詳解 ?? 資源管理 ?? 事件機制 ?? SpEL表達式語言 ?? 實戰案例 ?? 總…

Parasoft C++Test軟件集成測試(部件測試)_操作指南

系列文章目錄 Parasoft C++Test軟件靜態分析:操作指南(編碼規范、質量度量)、常見問題及處理 Parasoft C++Test軟件單元測試:操作指南、實例講解、常見問題及處理 Parasoft C++Test軟件集成測試:操作指南、實例講解、常見問題及處理 進階擴展:自動生成靜態分析文檔、自動…

聊一聊 Linux 上對函數進行 hook 的兩種方式

一:背景 1. 講故事 前兩篇我們介紹了 Minhook 在 Windows 平臺上的強大功效,這一篇我們來聊一聊如何在 Linux 上對函數進行hook,這里介紹兩種方式。 輕量級的 LD_PRELOAD 攔截 LD_PRELOAD是一種共享庫攔截,這種方式的優點在于…

【免費分享】GWO-BP-AdaBoost預測!灰狼優化、人工神經網絡與AdaBoost集成學習算法預測研究

一、模型組成原理 1. 灰狼優化算法(GWO) 核心思想:模擬灰狼群體的社會等級和狩獵行為(包圍、跟蹤、攻擊獵物),通過α、β、δ三級領導層引導種群搜索最優解。算法流程包括: 社會分層&#xff…

matlab實現非線性Granger因果檢驗

matlab程序包。用于格蘭杰因果分析,分析數據時,直接帶入數據即可。 hjt2/README , 1804 hjt2/c-code/Makefile , 57 hjt2/c-code/hjt2_tval.c , 10862 hjt2/matlab/spx_rp.dat , 175202 hjt2/matlab/spx_ur.dat , 174522 hjt2/matlab/spx_uv.dat , 1745…

從SQL Server到分布式大數據平臺:重構企業數據架構

在企業數字化加速的背景下,越來越多的組織開始意識到:傳統的數據系統正逐漸成為增長的“瓶頸”而非“助力”。其中,SQL Server 作為許多企業IT架構中曾經的中堅力量,正面臨前所未有的挑戰。它曾以穩定、易用、成本可控等優勢&…

【網關】互聯網公司的接入網關和業務網關怎么設計

網關 網關基礎知識 RGW全稱 Red GateWay :小紅書網關(網關英文:Gateway; 接入網關:Access Gateway) 網關(通用):Gateway 接入網關:API Gateway、Access Gateway 業務網關…

安全虛擬磁盤技術的創新與實踐

文章目錄 前言一、數據安全保護的新挑戰1. 數據安全態勢日益嚴峻,法律法規陸續出臺2. 加強數據安全管控成為銀行數據安全管理核心之一3. 銀行終端數據安全管控存在的難題 二、安全虛擬磁盤的探索與實踐1. 敏感文件的入盤及操作2. 敏感文件的流轉及出盤三、安全虛擬磁…

uni-app項目實戰筆記4--使用組件具名插槽slot定義公共標題模塊

先來看效果: 如圖,“每日推薦”,“專題精選”這些公共標題有相同的地方,也有自己的獨特的地方,像這類有共性又有個性的可考慮使用slot插槽來實現。 實現步驟: 1.在前面文章創建的公共組件common-title定義…

Appium + Java 測試全流程

??親愛的技術愛好者們,熱烈歡迎來到 Kant2048 的博客!我是 Thomas Kant,很開心能在CSDN上與你們相遇~?? 本博客的精華專欄: 【自動化測試】

vue3 雙容器自動擴展布局 根據 內容的多少 動態定義寬度

需求: 左右兩個列表 挨著排列,當左邊內容超出滾動條時,換列顯示,右邊的列表隨之移動 效果圖: 1.左邊數據:10,右邊數據:5 2.左邊數據:30,右邊數據&#xff…

linux-java部署

version: 3 services:nacos_host:image: nacos/nacos-server:v2.2.0restart: alwayscontainer_name: nacos_hostenvironment:- MODEstandalone- PREFER_HOST_MODEhostnamevolumes:- ./sores/nacos/log:/home/nacos/logsports:- 8848:8848- 9848:9848 #2.0新增了兩個端口&#x…

010502管道符_防火墻出入站_不回顯帶外-滲透命令-基礎入門-網絡安全

文章目錄 1 管道符2 防火墻出入站3 不回顯外帶典型場景常見OOB通道實現示例(以DNS為例)1. 利用DNS外帶數據2. 使用工具監聽 防御建議擴展:無回顯OOB自動化工具注意事項演示結語 1 管道符 | (管道符號) ||(…

智慧養老與數字健康:科技賦能老年生活,構建全方位養老體系

在全球人口老齡化進程不斷加速的當下,我國的老齡化程度也日益加深。 截至 2023 年末,我國 60 歲及以上人口達 2.97 億人,占總人口的 21.1%,其中 65 歲及以上人口為 2.17 億人,占總人口的 15.4%。 養老問題已成為全社…

在 cuda 基礎環境中安裝完整的cupy

nvidia/cuda:12.6.3-cudnn-devel-ubuntu22.04 1. 創建 cuda 基礎容器 export NUM2 && \ sudo docker run --gpus all -it \ --name cupy_LHL_${NUM} \ -v /home/jimmy/ex_cupy/tmp${NUM}:/root/tmp${NUM} \ -v /home/jimmy/.ssh:/root/.ssh \ nvidia/cuda:12.6.3-dev…

OB Cloud × 海牙灣:打造高效靈活的金融科技 AI 數字化解決方案

在金融行業國產升級的戰略背景下,上海海牙灣信息科技有限公司憑借其服務銀行客戶的深厚積累,近日完成重大技術升級 —— 將金融行業積分生態的SaaS平臺、數字化營銷中臺及企業供應鏈管理系統全部遷移至完全自主研發的 OB Cloud 一體化云數據庫。依托OB C…

LarkXR 賦能AI x XR數字供應鏈:引領智能設計、數字孿生與零售新未來

全球零售業數字化轉型 在數字化浪潮的推動下,零售業正經歷一場從設計到生產再到終端消費的全鏈路變革。消費者對個性化、沉浸式體驗的需求日益增長,而企業也亟需通過數字化手段提升效率、降低成本并增強競爭力。Paraverse平行云的LarkXR實時云渲染技術&…

go語言快速入門

代碼倉庫 gitee 如何運行 以打印hello world為例 // main.go package main // package為main的文件可以直接運行import "fmt"func main() {fmt.Println("Hello, World!") }# 直接運行 go run main.go # 或者編譯后運行 go build main.go ./main.exe變量…

使用麒麟V10操作系統的KVM服務,但麒麟V10存在高危漏洞無法修復?

麒麟V10操作系統之KVM部署虛擬機_麒麟v10安裝kvm-CSDN博客文章瀏覽閱讀3.7k次,點贊30次,收藏25次。本文介紹了在麒麟V10操作系統上部署KVM虛擬機的詳細步驟,包括檢查虛擬化支持、安裝KVM組件、創建虛擬機、配置網絡橋接,以及解決可…

PG、SprinBoot項目報錯,表不存在

1、用戶名密碼錯誤 2、數據庫IP和數據庫名稱錯誤 3、類似于如下的表結構 PG 默認掃描PUBLIC下面的表,需要手動指定schema,currentSchemaswdn_new url: jdbc:postgresql://${PGSQL_HOST:127.0.0.1}:${PGSQL_PORT:5432}/swdn_new?currentSchemaswdn_ne…