Spring虽无内置事件总线,但可通过ApplicationEvent与@EventListener构建轻量、解耦、线程安全的事件机制;推荐使用POJO事件,配合ApplicationEventPublisher发布及@EventListener监听,支持同步、异步(@Async)和事务绑定(@TransactionalEventListener)。

Spring 本身没有内置“事件总线”(Event Bus)概念,但通过其 ApplicationEvent + @EventListener 机制,可以自然地构建出轻量、解耦、线程安全的事件总线行为。关键不在于“造轮子”,而在于正确组织事件、发布和监听逻辑。
定义自定义事件类型
继承 ApplicationEvent 或直接使用泛型事件(推荐 Spring 4.2+ 的普通 POJO 事件):
public class OrderCreatedEvent {
private final String orderId;
private final BigDecimal amount;
public OrderCreatedEvent(String orderId, BigDecimal amount) {
this.orderId = orderId;
this.amount = amount;
}
// getter...
}
✅ 优势:无需继承、更简洁;Spring 会自动识别为事件并完成传播。
在业务中发布事件
注入 ApplicationEventPublisher,在需要触发通知的地方发布:
立即学习“Java免费学习笔记(深入)”;
@Service
public class OrderService {
@Autowired
private ApplicationEventPublisher publisher;
public void createOrder(String orderId, BigDecimal amount) {
// 1. 执行核心逻辑(如保存订单)
// 2. 发布事件
publisher.publishEvent(new OrderCreatedEvent(orderId, amount));
}
}
⚠️ 注意:默认是同步调用,监听器在同一线程执行;如需异步,需配合 @Async 和启用异步支持。
编写监听器(订阅者)
用 @EventListener 标注任意 Bean 中的方法,支持多种写法:
- 按事件类型自动匹配:
@EventListener(OrderCreatedEvent.class) - 监听多个事件:
@EventListener({OrderCreatedEvent.class, PaymentCompletedEvent.class}) - 条件过滤(SpEL):
@EventListener(condition = "#event.amount > 100") - 指定顺序:
@EventListener @Order(10)
@Component
public class InventoryListener {
@EventListener
public void onOrderCreated(OrderCreatedEvent event) {
System.out.println("扣减库存: " + event.getOrderId());
// 调用库存服务...
}
}
进阶:支持异步与事务绑定
若监听逻辑耗时或需脱离主事务(如发短信、写日志),可结合 @Async:
- 确保配置了
@EnableAsync,且监听方法所在类由 Spring 管理 - 默认事务上下文不传播到异步监听器 —— 这通常是期望行为(避免因监听失败回滚主流程)
- 如需事务内执行(例如“发消息前必须确保数据库已提交”),改用
@TransactionalEventListener,它支持phase = TransactionPhase.AFTER_COMMIT
@EventListener
@TransactionalEventListener(phase = TransactionPhase.AFTER_COMMIT)
public void sendNotificationAfterCommit(OrderCreatedEvent event) {
// 只有事务真正提交后才执行
smsService.send("订单创建成功:" + event.getOrderId());
}
不复杂但容易忽略:事件机制本质是观察者模式的声明式实现,Spring 已帮你处理线程安全、Bean 生命周期集成和上下文传播。专注定义“什么发生了”和“谁关心”,其余交给容器。


















