电脑知识|欧美黑人一区二区三区|软件|欧美黑人一级爽快片淫片高清|系统|欧美黑人狂野猛交老妇|数据库|服务器|编程开发|网络运营|知识问答|技术教程文章 - 好吧啦网

您的位置:首頁技術文章
文章詳情頁

SpringBoot事件機制相關知識點匯總

瀏覽:73日期:2023-04-28 11:06:53

要“監聽”事件,我們總是可以將“監聽器”作為事件源中的另一個方法寫入事件,但這將使事件源與監聽器的邏輯緊密耦合。

對于實際事件,我們比直接方法調用更靈活。我們可以根據需要動態注冊和注銷某些事件的偵聽器。我們還可以為同一事件設置多個偵聽器。

本教程概述了如何發布和偵聽自定義事件,并解釋了 Spring Boot 的內置事件。

為什么我應該使用事件而不是直接方法調用?

事件和直接方法調用都適合于不同的情況。使用方法調用,就像斷言一樣-無論發送和接收模塊的狀態如何,他們都需要知道此事件的發生。

對于事件,另一方面,我們只知道發生了一個事件,哪些模塊會被通知并不是我們關心的問題。當我們想要將某些業務處理傳遞給另一個線程時(例如:在某些任務完成時發送電子郵件),最好使用事件。此外,事件對于測試驅動的開發也很有用。

什么是應用程序事件( Application Events)?

Spring 應用程序事件允許我們發送和接收特定應用程序事件,我們可以根據需要處理這些事件。事件用于在松散耦合的組件之間交換信息。由于發布者和訂閱者之間沒有直接耦合,因此可以在不影響發布者的情況下修改訂閱者,反之亦然。

讓我們看看如何在 Spring Boot 應用程序中創建、發布和偵聽自定義事件。

創建ApplicationEvent

我們可以使用 Spring Framework 的事件發布機制發布應用程序事件。

讓我們通過擴展來創建調用的自定義事件:

class UserCreatedEvent extends ApplicationEvent { private String name; UserCreatedEvent(Object source, String name) { super(source); this.name = name; } ...}

代碼中super(source)中的source應該是最初發生事件的對象或與事件相關聯的對象。

從Spring 4.2開始,我們還可以將對象發布為事件,而無需擴展ApplicationEvent:

class UserRemovedEvent { private String name; UserRemovedEvent(String name) { this.name = name; } ...}

發布一個ApplicationEvent

我們使用ApplicationEventPublisher接口發布事件:

@Componentclass Publisher { private final ApplicationEventPublisher publisher; Publisher(ApplicationEventPublisher publisher) { this.publisher = publisher; } void publishEvent(final String name) { // Publishing event created by extending ApplicationEvent publisher.publishEvent(new UserCreatedEvent(this, name)); // Publishing an object as an event publisher.publishEvent(new UserRemovedEvent(name)); }}

當我們發布的對象不是ApplicationEvent時,Spring會自動為我們將其包裝在PayloadApplicationEvent中。

接收應用程序事件

現在,我們知道如何創建和發布自定義事件,讓我們看看如何偵聽該事件。事件可以有多個偵聽器并且根據應用程序要求執行不同的工作。

有兩種方法可以定義偵聽器。我們可以使用注解(@EventListener)或實現接口(ApplicationListener)。在這兩種情況下,偵聽器類都必須由 Spring 管理。

注解

從Spring 4.1開始,可以使用@EventListener注解的方法,以自動注冊與該方法簽名匹配的ApplicationListener:

@Componentclass UserRemovedListener { @EventListener ReturnedEvent handleUserRemovedEvent(UserRemovedEvent event) { // handle UserRemovedEvent ... return new ReturnedEvent(); } @EventListener void handleReturnedEvent(ReturnedEvent event) { // handle ReturnedEvent ... } ...}

啟用注解驅動的配置時,不需要其他配置。我們的方法可以監聽多個事件,或者如果我們想完全不使用任何參數來定義它,那么事件類型也可以在注解本身上指定。示例:@EventListener({ContextStartedEvent.class,ContextRefreshedEvent.class})。

對于使用@EventListener注解并定義為具有返回類型的方法,Spring會將結果作為新事件發布給我們。在上面的示例中,第一個方法返回的ReturnedEvent將被發布,然后由第二個方法處理。

如果指定SpEL條件,Spring僅在某些情況下才允許觸發我們的偵聽器:

@Componentclass UserRemovedListener { @EventListener(condition = '#event.name eq ’reflectoring’') void handleConditionalListener(UserRemovedEvent event) { // handle UserRemovedEvent }}

僅當表達式的計算結果為true或以下字符串之一時才處理該事件:“ true”,“ on”,“ yes”或“ 1”。方法參數通過其名稱公開。條件表達式還公開了一個“ root”變量,該變量引用原始ApplicationEvent(#root.event)和實際方法參數(#root.args)

在以上示例中,僅當#event.name的值為’reflectoring’時,才會使用UserRemovedEvent觸發監聽器。

實現ApplicationListener接口

偵聽事件的另一種方法是實現ApplicationListener接口:

@Componentclass UserCreatedListener implements ApplicationListener<UserCreatedEvent> { @Override public void onApplicationEvent(UserCreatedEvent event) { // handle UserCreatedEvent }}

只要偵聽器對象在Spring應用程序上下文中注冊,它就會接收事件。當Spring路由一個事件時,它使用偵聽器的簽名來確定它是否與事件匹配。

異步事件偵聽器

默認情況下,spring事件是同步的,這意味著發布者線程將阻塞,直到所有偵聽器都完成對事件的處理為止。

要使事件偵聽器以異步模式運行,我們要做的就是在該偵聽器上使用@Async注解:

@Componentclass AsyncListener { @Async @EventListener void handleAsyncEvent(String event) { // handle event }}

為了使@Async注解起作用,我們還必須使用@EnableAsync注解我們的@Configuration類之一或@SpringBootApplication類。

上面的代碼示例還顯示了我們可以將String用作事件。使用風險自負。最好使用特定于我們用例的數據類型,以免與其他事件沖突。

Transaction-綁定事件

Spring允許我們將事件偵聽器綁定到當前事務的某個階段。如果當前事務的結果對偵聽器很重要時,這使事件可以更靈活地使用。

當我們使用@TransactionalEventListener注釋方法時,我們將獲得一個擴展的事件偵聽器,該偵聽器可以了解事務:

@Componentclass UserRemovedListener { @TransactionalEventListener(phase=TransactionPhase.AFTER_COMPLETION) void handleAfterUserRemoved(UserRemovedEvent event) { // handle UserRemovedEvent }}

僅當當前事務完成時才調用UserRemovedListener。

我們可以將偵聽器綁定到事務的以下階段:

AFTER_COMMIT:事務成功提交后,將處理該事件。如果事件偵聽器僅在當前事務成功時才運行,則可以使用此方法。

AFTER_COMPLETION:事務提交或回滾時將處理該事件。例如,我們可以使用它在事務完成后執行清理。

AFTER_ROLLBACK:事務回滾后將處理該事件。

BEFORE_COMMIT:該事件將在事務提交之前進行處理。例如,我們可以使用它來將事務性ORM會話刷新到數據庫。

Spring Boot的 Application Events

Spring Boot提供了幾個與SpringApplication生命周期相關的預定義ApplicationEvent。

在創建ApplicationContext之前會觸發一些事件,因此我們無法將這些事件注冊為@Bean。我們可以通過手動添加偵聽器來注冊這些事件的偵聽器:

@SpringBootApplicationpublic class EventsDemoApplication { public static void main(String[] args) { SpringApplication springApplication = new SpringApplication(EventsDemoApplication.class); springApplication.addListeners(new SpringBuiltInEventsListener()); springApplication.run(args); }}

通過將META-INF/spring.factories文件添加到我們的項目中,我們還可以注冊偵聽器,而不管如何創建應用程序,并使用

org.springframework.context.ApplicationListener鍵引用偵聽器:

org.springframework.context.ApplicationListener= com.reflectoring.eventdemo.SpringBuiltInEventsListener

class SpringBuiltInEventsListener implements ApplicationListener<SpringApplicationEvent>{ @Override public void onApplicationEvent(SpringApplicationEvent event) { // handle event }}

確定事件監聽器已正確注冊后,便可以監聽所有Spring Boot的SpringApplicationEvents。讓我們按照它們在應用程序啟動過程中的執行順序來進行觀察。

ApplicationStartingEvent

除了運行偵聽器和初始化程序的注冊之外,ApplicationStartingEvent在運行開始時但在任何處理之前都會觸發。

ApplicationEnvironmentPreparedEvent

當上下文中使用的環境可用時,將觸發ApplicationEnvironmentPreparedEvent。

由于此時環境已準備就緒,因此我們可以在其他Bean使用它之前對其進行檢查和修改。

ApplicationContextInitializedEvent

當ApplicationContext準備就緒并且調用ApplicationContextInitializers但尚未加載bean定義時,將觸發ApplicationContextInitializedEvent。

在bean初始化到Spring容器之前,我們可以使用它來執行任務。

ApplicationPreparedEvent

準備好ApllicationContext但未刷新時會觸發ApplicationPreparedEvent。

該環境已準備就緒,可以使用,并且將加載Bean定義。

WebServerInitializedEvent

如果我們使用的是網絡服務器,則在網絡服務器準備就緒后會觸發WebServerInitializedEvent。 ServletWebServerInitializedEvent和ReactiveWebServerInitializedEvent分別是servlet和反應式網絡服務。

WebServerInitializedEvent不擴展SpringApplicationEvent。

ApplicationStartedEvent

在刷新上下文之后但在調用任何應用程序和命令行運行程序之前,將觸發ApplicationStartedEvent。

ApplicationReadyEvent

觸發ApplicationReadyEvent來指示該應用程序已準備就緒,可以處理請求。

建議此時不要修改內部狀態,因為所有初始化步驟都將完成。

ApplicationFailedEvent

如果存在異常并且應用程序無法啟動,則會觸發ApplicationFailedEvent。在啟動期間的任何時間都可能發生這種情況。

我們可以使用它來執行一些任務,例如執行腳本或在啟動失敗時發出通知。

結論

事件是為在同一應用程序上下文內的Spring Bean之間進行簡單通信而設計的。從Spring 4.2開始,基礎結構已得到顯著改進,并提供了基于注釋的模型以及發布任意事件的功能。

英文原文:https://reflectoring.io/spring-boot-application-events-explained/

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持好吧啦網。

標簽: Spring
相關文章:
主站蜘蛛池模板: 中视电广_短视频拍摄_短视频推广_短视频代运营_宣传片拍摄_影视广告制作_中视电广 | 台湾阳明固态继电器-奥托尼克斯光电传感器-接近开关-温控器-光纤传感器-编码器一级代理商江苏用之宜电气 | 品牌广告服务平台,好排名,好流量,好生意。 | 自动化展_机器人展_机床展_工业互联网展_广东佛山工博会 | 济南玻璃安装_济南玻璃门_济南感应门_济南玻璃隔断_济南玻璃门维修_济南镜片安装_济南肯德基门_济南高隔间-济南凯轩鹏宇玻璃有限公司 | 工业车间焊接-整体|集中除尘设备-激光|等离子切割机配套除尘-粉尘烟尘净化治理厂家-山东美蓝环保科技有限公司 | 空气净化器租赁,空气净化器出租,全国直租_奥司汀净化器租赁 | 钢托盘,铁托盘,钢制托盘,镀锌托盘,饲料托盘,钢托盘制造商-南京飞天金属13260753852 | 高压贴片电容|贴片安规电容|三端滤波器|风华电容代理南京南山 | 团建-拓展-拓展培训-拓展训练-户外拓展训练基地[无锡劲途] | 食品无尘净化车间,食品罐装净化车间,净化车间配套风淋室-青岛旭恒洁净技术有限公司 | 环讯传媒,永康网络公司,永康网站建设,永康小程序开发制作,永康网站制作,武义网页设计,金华地区网站SEO优化推广 - 永康市环讯电子商务有限公司 | 全自动端子机|刺破式端子压接机|全自动双头沾锡机|全自动插胶壳端子机-东莞市傅氏兄弟机械设备有限公司 | 西点培训学校_法式西点培训班_西点师培训_西点蛋糕培训-广州烘趣西点烘焙培训学院 | 平面钻,法兰钻,三维钻-山东兴田阳光智能装备股份有限公司 | HYDAC过滤器,HYDAC滤芯,现货ATOS油泵,ATOS比例阀-东莞市广联自动化科技有限公司 | 都江堰招聘网-都江堰人才网 都江堰人事人才网 都江堰人才招聘网 邢台人才网_邢台招聘网_邢台123招聘【智达人才网】 | 大巴租车平台承接包车,通勤班车,巴士租赁业务 - 鸿鸣巴士 | 利浦顿蒸汽发生器厂家-电蒸汽发生器/燃气蒸汽发生器_湖北利浦顿热能科技有限公司官网 | 日本SMC气缸接头-速度控制阀-日本三菱伺服电机-苏州禾力自动化科技有限公司 | 干粉砂浆设备-干粉砂浆生产线-干混-石膏-保温砂浆设备生产线-腻子粉设备厂家-国恒机械 | 贝壳粉涂料-内墙腻子-外墙腻子-山东巨野七彩贝壳漆业中心 | 防爆电机_ybx3系列电机_河南省南洋防爆电机有限公司 | 清水混凝土修复_混凝土色差修复剂_混凝土色差调整剂_清水混凝土色差修复_河南天工 | 新中天检测有限公司青岛分公司-山东|菏泽|济南|潍坊|泰安防雷检测验收 | 无压烧结银_有压烧结银_导电银胶_导电油墨_导电胶-善仁(浙江)新材料 | 苏州工作服定做-工作服定制-工作服厂家网站-尺品服饰科技(苏州)有限公司 | 闭端端子|弹簧螺式接线头|防水接线头|插线式接线头|端子台|电源线扣+护线套|印刷电路板型端子台|金笔电子代理商-上海拓胜电气有限公司 | 立式硫化罐-劳保用品硫化罐-厂家直销-山东鑫泰鑫硫化罐厂家 | 凝胶成像仪,化学发光凝胶成像系统,凝胶成像分析系统-上海培清科技有限公司 | 聚氨酯保温钢管_聚氨酯直埋保温管道_聚氨酯发泡保温管厂家-沧州万荣防腐保温管道有限公司 | 振动传感器,检波器-威海广达勘探仪器有限公司 | 萃取箱-萃取槽-PVC萃取箱厂家-混合澄清槽- 杭州南方化工设备 | 自动检重秤-动态称重机-重量分选秤-苏州金钻称重设备系统开发有限公司 | 贝朗斯动力商城(BRCPOWER.COM) - 买叉车蓄电池上贝朗斯商城,价格更超值,品质有保障! | 铁盒_铁罐_马口铁盒_马口铁罐_铁盒生产厂家-广州博新制罐 | 工业风机_环保空调_冷风机_工厂车间厂房通风降温设备旺成服务平台 | 矿用履带式平板车|探水钻机|气动架柱式钻机|架柱式液压回转钻机|履带式钻机-启睿探水钻机厂家 | 假肢-假肢价格-假肢厂家-河南假肢-郑州市力康假肢矫形器有限公司 | RTO换向阀_VOC高温阀门_加热炉切断阀_双偏心软密封蝶阀_煤气蝶阀_提升阀-湖北霍科德阀门有限公司 | 电动高尔夫球车|电动观光车|电动巡逻车|电动越野车厂家-绿友机械集团股份有限公司 |