一、spring 事件驱动完整流程总结
1. 定义事件:基类封装 + 业务事件继承
(1)事件基类:testevent(继承 spring 标准 applicationevent)
作用:封装通用事件数据,作为所有相关事件的父类,减少重复代码。
核心:继承 applicationevent,通过构造器传递事件源(source) 和通用业务数据(cmd),并提供 getter 供子类 / 监听器获取。
// 事件基类:封装通用事件数据(可根据业务选择是否需要通用事件封装)
public class testevent extends applicationevent {
@getter
private commontestdata cmd;
// 构造器:必传事件源 + 通用业务数据
public testevent(object source, commontestdata cmd) {
super(source); // 调用父类applicationevent构造器,绑定事件源
this.cmd = cmd;
}
}(2)业务事件:realtimetestevent(继承 testevent)
作用:基于基类扩展,定义具体业务场景的事件,无需重复封装通用数据。
核心:直接复用父类 testevent 的构造器,仅传递业务所需参数,简化事件定义。
// 业务事件:继承testevent,专注业务场景
public class realtimetestevent extends testevent {
// 直接复用父类构造器,传递事件源 + 业务数据cmd
public realtimetestevent(object source, commontestdata cmd) {
super(source, cmd);
}
}
2. 发布事件:业务方法中触发
注入 spring 内置 applicationeventpublisher,在核心业务逻辑完成后发布事件。
可通过开关(如 istesteventtestenable)控制是否发布,灵活适配业务需求。
@autowired
private applicationeventpublisher eventpublisher;
// 业务方法中发布事件(核心逻辑执行后)
if (istesteventtestenable) {
// 构造业务事件,传递事件源(this) + 业务数据md
eventpublisher.publishevent(new realtimetestevent(this, md));
}3. 监听事件:异步监听 + 自定义线程池
监听器类加 @service(或 @component),被 spring 容器管理。
用 @eventlistener 绑定具体事件,@async 指定自定义线程池,实现异步非阻塞处理。
从事件中通过 getcmd() 获取通用业务数据,执行附加逻辑。
@slf4j
@service
public class realtimetesteventlistener {
@sneakythrows
// 1. 指定自定义线程池,异步执行(不阻塞主线程)
@async("realtimetesteventthreadpool")
// 2. 监听realtimetestevent事件(匹配事件类型)
@eventlistener(realtimetestevent.class)
public void handleevent(realtimetestevent event) {
// 从事件基类testevent中获取通用业务数据
commontestdata md = event.getcmd();
// 执行业务附加逻辑
mktdatatestrealtimelistener.pushrealtimetest(
...
);
}
}4. 线程池配置:自定义隔离 + 动态参数
用 @configuration 声明配置类,@bean 定义线程池,供 @async 调用。
从配置文件读取线程池参数(核心数、最大数、队列容量),支持动态调整。
设置线程名前缀,方便日志排查;配置拒绝策略(如 callerrunspolicy)避免任务丢失。
@configuration
public class testeventthreadpool {
@autowired
private threadpoolproperties threadpoolproperties;
// 定义线程池bean,指定名称供@async调用
@bean("realtimetesteventthreadpool")
public executor realtimetesteventthreadpool() {
threadpooltaskexecutor taskexecutor = new threadpooltaskexecutor();
// 动态读取配置参数
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:核心区别与适用场景
1. 核心区别(一句话总结)
@eventlistener:事件发布即执行,不依赖事务状态;
@transactionaleventlistener:绑定事务阶段执行(如事务提交后),专为事务场景设计。
2.关键事务阶段(phase)
@transactionaleventlistener 支持 4 种事务阶段,按需选择:
transactionphase.before_commit:事务提交前执行(慎用,可能阻塞事务提交);
transactionphase.after_commit:事务提交成功后执行(最常用,保证数据一致性);
transactionphase.after_rollback:事务回滚后执行(如回滚补偿逻辑);
transactionphase.after_completion:事务完成后(无论提交 / 回滚)执行。
3. 适用场景选型(结合你的业务)
(1)用 @eventlistener 的场景
业务无数据库事务,或事务与事件处理无数据依赖;不操作数据库,无数据一致性风险,用 @eventlistener 更简洁高效。
事件处理是轻量操作(如推送消息、记录日志、更新缓存),无需等待事务提交;
(2)用 @transactionaleventlistener 的场景
事件处理依赖主事务的数据库数据(如主事务更新数据后,监听器需读取最新数据);
需避免 “事务未提交,监听器读取脏数据” 的问题;
三、整体核心价值总结
代码复用:通过 testevent 基类封装通用事件数据,业务事件仅需继承,减少重复代码;
业务解耦:主业务只负责发布事件,监听器独立处理附加逻辑,新增 / 删除逻辑无需修改主业务;
性能优化:@async + 自定义线程池,让附加逻辑异步执行,不阻塞主线程,提升接口响应速度;
稳定性保障:自定义线程池控制并发,避免默认线程池的 oom 风险;@transactionaleventlistener 解决事务场景的数据一致性问题;
灵活扩展:支持多事件、多监听器、多线程池隔离,适配复杂业务场景。
四、快速选型口诀
非事务、轻量处理、无数据依赖 → 用 @eventlistener;
事务场景、需读最新事务数据、保证一致性 → 用 @transactionaleventlistener(phase = after_commit)。
五、spring 事件驱动和消息中间件选型
(1)、spring 事件驱动:仅适用于同一个服务(进程内) 本地解耦
spring 事件驱动(applicationevent/@eventlistener/@transactionaleventlistener)的底层是基于 spring 容器的内存事件广播机制,事件的发布、监听全程都在同一个 jvm 进程内完成,无法跨服务、跨进程、跨服务器传递。
核心价值:解决单服务内部的业务解耦问题;
优势:轻量、无中间件依赖、执行效率高、无需考虑网络 / 序列化问题;
局限:仅单服务有效,服务集群部署时,事件仅在当前发布事件的服务实例中触发,其他实例无法感知。
(2)、跨服务解耦:必须使用消息中间件(主流选型)
当需要跨服务、跨进程、跨服务器传递事件 / 消息时,spring 事件驱动完全无法满足,此时消息中间件(mq) 是标准且唯一的解决方案,其核心作用是实现分布式系统中的异步通信与解耦。
主流消息中间件选型(按场景适配):
rabbitmq:基于 amqp 协议,支持丰富的消息路由(直连、主题、扇出等)、消息确认、死信队列,适配复杂的业务场景(如订单支付后跨服务通知库存、物流),企业级项目首选;
kafka:基于发布 - 订阅模式,高吞吐、低延迟、高可用,适合大数据量、高并发的日志收集、实时数据同步、流处理场景;
rocketmq:阿里开源,兼顾 rabbitmq 的功能丰富性和 kafka 的高吞吐,支持分布式事务消息,适合电商、金融等核心业务场景;
activemq:老牌消息中间件,协议支持全面,但性能和高可用略逊于前三者,适合中小型项目或传统项目。
到此这篇关于spring 事件驱动用法完整流程的文章就介绍到这了,更多相关spring 事件驱动用法内容请搜索代码网以前的文章或继续浏览下面的相关文章希望大家以后多多支持代码网!
发表评论