用途
Spring Application Events 技能用于在 Spring Boot 3.x 应用中实现基于应用内事件的解耦通信。它围绕 Spring 框架自带的事件发布/监听机制,帮助开发者把业务动作(如订单创建)与后续副作用(如发送通知、记录日志)分离,降低模块间直接依赖。
主要能力
- 事件发布:通过 ApplicationEventPublisher 的 publishEvent 方法发布事件,示例中在 @Transactional 的 createOrder 方法内发布 OrderCreatedEvent。
- 自定义事件:推荐使用 record 定义不可变 POJO 事件,如 OrderCreatedEvent 包含 orderId、customerId、totalAmount、createdAt 等字段;也支持泛型事件 EntityEvent<T> 与 EventType 枚举(CREATED、UPDATED、DELETED)。
- @EventListener:支持基础监听、条件监听(condition = "#event.totalAmount > 1000")、通过 @Order 控制执行顺序、一次监听多种事件类型(@EventListener({OrderCreatedEvent.class, OrderUpdatedEvent.class}))。
- 事件链:监听器方法可返回新事件(单个或 Collection<Object>),由框架继续发布,例如订单创建后返回 NotificationEvent。
- @TransactionalEventListener:支持 AFTER_COMMIT(默认)、AFTER_ROLLBACK、BEFORE_COMMIT 三种事务阶段,以及 fallbackExecution = true 在无事务时回退执行。
- 异步事件:资料提到 @Async 用于非关键操作,并指向 transactional.md 参考文件。
使用方式
- 定义事件类(推荐 record 保证不可变)。
- 在服务中注入 ApplicationEventPublisher,在业务逻辑中调用 publishEvent。
- 编写监听组件,使用 @EventListener 或 @TransactionalEventListener 标注处理方法;组件需被扫描到(如加 @Component)。
- 需要顺序时用 @Order 标注;需要条件时用 condition 表达式;需要事务后执行副作用时用 @TransactionalEventListener。
- 异步场景需在配置中启用 @EnableAsync。
适用场景
- 单体或模块化 Spring Boot 应用内的领域事件解耦。
- 事务提交后触发外部调用(如发送订单确认邮件)。
- 非关键操作异步化,避免阻塞发布方。
- 需要在事务回滚时执行告警或补偿逻辑。
限制与注意事项
- 不适用:分布式事件应使用 spring-kafka 或 spring-amqp;需要保证投递应使用消息系统;事件溯源可考虑 Axon Framework。
- 常见陷阱:监听器未执行通常是缺少 @Component;回滚导致事件丢失通常是误用 @EventListener 而非 @TransactionalEventListener;同步监听器调用同一服务可能死锁,应改用 @Async;异步 void 方法会隐藏异常,需实现错误处理器。
- 反模式:事务内同步事件导致长事务;循环发布事件造成无限循环;同步监听中做重处理阻塞发布方;发布后修改事件引发共享状态问题。
- 最佳实践:副作用使用 @TransactionalEventListener;非关键操作使用 @Async;为易失败监听器实现重试;事件保持不可变;必要时用 @Order 定义顺序;不要在同步监听器中修改状态;不要假设没有 @Order 时的执行顺序。
- 生产检查清单:事件类不可变、外部调用使用 TransactionalEventListener、非关键操作异步化、实现错误处理、瞬时操作重试、监控事件。
- 资料中未提供具体版本兼容细节、性能数据或收费信息。