掘金 后端 ( ) • 2024-04-19 16:14

概述

Application Event是Spring提供的基于观察者模式的事件,该事件为Bean与Bean之间的消息通信提供了支持,是业务解耦的一种实现。当Bean-A处理完成一个任务之后,希望Bean-B知道并能做相应的处理,这时我们就需要让Bean-B监听Bean-A所发生的事件。

【这篇我们主要介绍SpringEvent支持的功能,实现原理在# 事件驱动模型的最佳实践-SpringEvent【(二)原理篇】中介绍】

不使用事件开发业务逻辑代码时,我们将某些操作的后置操作全都写在业务代码中,如下图: image.png

使用事件时,主流程完成后,我们只需要对外发送一个事件,在事件处理中做后续操作(发送邮件发送MQ): image.png

组成部分 image.png

1、基本使用

常用的事件都是同步处理

1.1、定义事件

图片.png

1.2、定义监听者

1.2.1 方式1-实现  ApplicationListener接口

图片.png

1.2.2 方式2-使用 @EventListener 注解

图片.png

1.3、事件发布

事件发布使用的是  ApplicationEventPublisher,这是springEvent 自带publisher,自动注入就可使用。 图片.png

图片.png

1.4、执行结果

图片.png

2、条件过滤

在某些场景下,我们希望listener能根据消息中的某些条件来过滤消息。 springEvent 支持在注册listener的注释中加上一些条件来进行过滤消息。

2.1 条件listener 注册

第一个 只有 itemEvent.message 等于 itemEvent11111111111111 时,才会进行消息处理

第二个 只有 itemEvent.message 等于 111111111时,才会进行消息处理 图片.png

2.1 执行结果

消息发送 为   itemEvent11111111111111  图片.png

只有 itemEventListenerConditionTrue 处理了消息 图片.png

3、指定listener执行顺序

在某些场景下,我们希望 itemEvent 的listener执行是有先后顺序。 springEvent 支持在listener上 添加 @Order 注释进行顺序编排

3.1 定义顺序 listener

图片.png

3.2 执行结果

图片.png

4、事务支持

我们希望商品修改事务提交成功后再处理更新事件。

springEvent 支持将消息的发送加入到本地事务中,需要我们在listener注册时,加上事务的注释(TransactionalEventListener)进行标记。

4.1 注册事务 listener

图片.png

消息发送的场景支持四种,其中默认为AFTER_COMMIT  ,具体枚举如下:

图片.png

4.2 代码详情

4.2.1 表对应实体

图片.png

4.2.2 mysql 数据

图片.png

4.2.3 含有事务的方法

此处举例了两个方法,一个成功、一个失败,用于做比较。

图片.png

4.3 执行结果

4.3.1 事务成功举例

图片.png

图片.png

4.3.2 事务执行失败举例

图片.png

图片.png

4.4 总结

BEFORE_COMMIT 事务开始前处理更新事件 AFTER_COMMIT 事务成功后处理更新事件 AFTER_ROLLBACK 事务失败后处理更新事件 AFTER_COMPLETION 事务结束后处理更新事件(注意,只是结束,无所谓成功与否)

5、异步事件

某些场景下,我们不希望消息的处理阻塞主线程。因此需要将消息处理异步化。

springEvent 异步处理消息时,会将任务提交到线程池中进行处理。

异步的事件定义和时间发送都是相同的,在定义listener时,需要加上异步的注释(@Async)

5.1 异步配置

一般我们会自定义一个线程池进行区分,不配置会使用默认配置。

图片.png

5.2 定义异步listener

异步listener 与同步listener没什么不同,只是多了一个异步的注释

图片.png

5.3 结果

图片.png