ApplicationEventPublisher
是 Spring 框架中 事件驱动编程模型 的核心接口,用于实现 观察者模式(Observer Pattern)。它允许 Bean 之间通过 发布-订阅机制 进行松耦合通信,适用于解耦业务逻辑、实现异步处理等场景。
1. ApplicationEventPublisher 的作用
1.1 核心功能
- 发布事件:允许任何 Spring Bean 发布自定义事件。
- 监听事件:其他 Bean 可以监听并处理这些事件,实现解耦。
- 支持同步/异步处理:默认同步,可配置为异步(结合
@Async
)。
1.2 典型应用场景
- 业务逻辑解耦:如订单创建后发送邮件、记录日志。
- 系统监控:如应用启动后初始化缓存。
- 异步任务:如耗时操作(短信发送)通过事件异步处理。
2. 核心组件
2.1 ApplicationEventPublisher 接口
public interface ApplicationEventPublisher {
void publishEvent(ApplicationEvent event); // 发布事件
void publishEvent(Object event); // Spring 4.2+ 支持任意对象作为事件
}
示例:
@Service
public class OrderService {
@Autowired
private ApplicationEventPublisher publisher;
public void createOrder(Order order) {
// 业务逻辑...
publisher.publishEvent(new OrderCreatedEvent(order)); // 发布订单创建事件
}
}
2.2 ApplicationEvent:事件基类
自定义事件需继承 ApplicationEvent
(Spring 4.2+ 后可直接用普通对象)。
public class OrderCreatedEvent extends ApplicationEvent {
private Order order;
public OrderCreatedEvent(Order order) {
super(order);
this.order = order;
}
public Order getOrder() { return order; }
}
2.3 ApplicationListener:事件监听器
实现 ApplicationListener
接口或使用 @EventListener
注解。
@Component
public class OrderEventListener implements ApplicationListener<OrderCreatedEvent> {
@Override
public void onApplicationEvent(OrderCreatedEvent event) {
System.out.println("收到订单创建事件,订单ID: " + event.getOrder().getId());
}
}
Spring 4.2+ 更简洁的注解方式:
@Component
public class EmailService {
@EventListener
public void handleOrderCreatedEvent(OrderCreatedEvent event) {
// 发送邮件...
}
}
3. 使用示例
3.1 同步事件处理
// 1. 定义事件
public class LogEvent {
private String message;
public LogEvent(String message) { this.message = message; }
// getter...
}
// 2. 发布事件
@Service
public class LogService {
@Autowired
private ApplicationEventPublisher publisher;
public void log(String message) {
publisher.publishEvent(new LogEvent(message));
}
}
// 3. 监听事件
@Component
public class LogEventListener {
@EventListener
public void handleLogEvent(LogEvent event) {
System.out.println("日志记录: " + event.getMessage());
}
}
3.2 异步事件处理
@Configuration
@EnableAsync
public class AsyncConfig implements AsyncConfigurer {
@Override
public Executor getAsyncExecutor() {
return Executors.newFixedThreadPool(5);
}
}
// 监听器添加 @Async
@Component
public class AsyncEventListener {
@Async
@EventListener
public void handleAsyncEvent(LogEvent event) {
System.out.println("异步处理日志: " + event.getMessage());
}
}
4. 高级特性
4.1 条件化监听(Conditional Listening)
通过 SpEL 表达式控制是否处理事件:
@EventListener(condition = "#event.message.startsWith('ERROR')")
public void handleErrorLog(LogEvent event) {
// 仅处理以 "ERROR" 开头的日志
}
4.2 泛型事件
Spring 4.2+ 支持泛型事件:
public class EntityCreatedEvent<T> {
private T entity;
// 构造方法、getter...
}
@EventListener
public void handleUserCreated(EntityCreatedEvent<User> event) {
// 处理 User 创建事件
}
4.3 事务绑定事件
监听器在事务提交后触发:
@TransactionalEventListener(phase = TransactionPhase.AFTER_COMMIT)
public void handleAfterCommit(OrderCreatedEvent event) {
// 仅在事务提交后执行
}
5. 与直接方法调用的对比
方式 | 耦合度 | 灵活性 | 适用场景 |
---|---|---|---|
直接调用 | 高(强依赖) | 低 | 简单逻辑,无需解耦 |
事件驱动 | 低(松耦合) | 高 | 复杂业务,需异步或扩展 |
6. 性能与最佳实践
- 避免滥用事件:简单逻辑直接调用更高效。
- 异步事件注意线程安全:确保监听器无共享状态。
- 合理使用事务事件:避免事务未提交时读取脏数据。
7. 总结
ApplicationEventPublisher
是 Spring 事件驱动模型的核心,用于解耦组件。- 关键组件:事件(
ApplicationEvent
)、发布者(ApplicationEventPublisher
)、监听器(@EventListener
)。 - 高级功能:异步处理、条件监听、泛型事件、事务绑定。
- 适用场景:业务解耦、异步任务、系统监控。