Spring事件机制与监听模式
Spring 的事件机制实现了发布-订阅模式(Observer Pattern),用于在应用内部解耦模块间的通信。
核心接口
public abstract class ApplicationEvent extends EventObject { public ApplicationEvent(Object source) { super(source); } }
@FunctionalInterface public interface ApplicationListener<E extends ApplicationEvent> extends EventListener { void onApplicationEvent(E event); }
public interface ApplicationEventPublisher { void publishEvent(ApplicationEvent event); void publishEvent(Object event); }
|
基本使用
1. 定义事件
public class OrderCreatedEvent extends ApplicationEvent { private final Long orderId; private final BigDecimal amount; public OrderCreatedEvent(Object source, Long orderId, BigDecimal amount) { super(source); this.orderId = orderId; this.amount = amount; } }
|
2. 发布事件
@Service public class OrderService { @Autowired private ApplicationEventPublisher eventPublisher; @Transactional public void createOrder(OrderRequest request) { Order order = orderDao.save(request); eventPublisher.publishEvent( new OrderCreatedEvent(this, order.getId(), order.getAmount()) ); } }
|
3. 监听事件
方式1:实现 ApplicationListener
@Component public class OrderCreatedListener implements ApplicationListener<OrderCreatedEvent> { @Override public void onApplicationEvent(OrderCreatedEvent event) { System.out.println("订单创建事件: " + event.getOrderId()); } }
|
方式2:@EventListener(推荐)
@Component public class OrderEventListeners { @EventListener public void handleOrderCreated(OrderCreatedEvent event) { System.out.println("订单创建: " + event.getOrderId()); } @EventListener public void sendSms(OrderCreatedEvent event) { smsService.sendOrderCreatedSms(event.getOrderId()); } @EventListener public void updateStats(OrderCreatedEvent event) { statsService.incrementOrderCount(); } }
|
异步事件
开启异步支持
@Configuration @EnableAsync public class AsyncConfig { @Bean(name = "eventAsyncExecutor") public Executor eventAsyncExecutor() { ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor(); executor.setCorePoolSize(5); executor.setMaxPoolSize(10); executor.setQueueCapacity(100); executor.setThreadNamePrefix("event-"); executor.initialize(); return executor; } }
|
异步监听
@Component public class AsyncOrderListeners { @EventListener @Async("eventAsyncExecutor") public void handleOrderCreated(OrderCreatedEvent event) { emailService.sendOrderEmail(event.getOrderId()); } }
|
注意:异步事件不能依赖事务上下文。
事务事件
场景
事件监听需要在事务提交后才执行(如发送消息)。
@TransactionalEventListener
@Component public class TransactionalOrderListeners { @EventListener @TransactionalEventListener(phase = TransactionPhase.AFTER_COMMIT) public void sendMessage(OrderCreatedEvent event) { messageService.sendOrderCreatedMessage(event.getOrderId()); } @TransactionalEventListener(phase = TransactionPhase.AFTER_ROLLBACK) public void handleRollback(OrderCreatedEvent event) { log.warn("订单创建回滚: " + event.getOrderId()); } }
|
事务阶段
| 阶段 |
说明 |
| BEFORE_COMMIT |
事务提交前 |
| AFTER_COMMIT |
事务提交后(默认) |
| AFTER_ROLLBACK |
事务回滚后 |
| AFTER_COMPLETION |
事务完成后(提交或回滚) |
事件传播机制
ApplicationEventMulticaster
public interface ApplicationEventMulticaster { void addApplicationListener(ApplicationListener<?> listener); void removeApplicationListener(ApplicationListener<?> listener); void multicastEvent(ApplicationEvent event); }
|
默认实现:SimpleApplicationEventMulticaster
public class SimpleApplicationEventMulticaster extends AbstractApplicationEventMulticaster { @Override public void multicastEvent(ApplicationEvent event) { multicastEvent(event, resolveDefaultEventType(event)); } @Override public void multicastEvent(final ApplicationEvent event, ResolvableType eventType) { ResolvableType type = (eventType != null ? eventType : resolveDefaultEventType(event)); for (final ApplicationListener<?> listener : getApplicationListeners(event, type)) { Executor executor = getTaskExecutor(); if (executor != null) { executor.execute(() -> invokeListener(listener, event)); } else { invokeListener(listener, event); } } } }
|
自定义事件广播器
@Bean public ApplicationEventMulticaster applicationEventMulticaster() { SimpleApplicationEventMulticaster multicaster = new SimpleApplicationEventMulticaster(); multicaster.setTaskExecutor(eventAsyncExecutor()); multicaster.setErrorHandler(t -> log.error("事件处理异常", t)); return multicaster; }
|
泛型事件
使用 ResolvableType
public class EntityCreatedEvent<T> extends ApplicationEvent { private final T entity; public EntityCreatedEvent(Object source, T entity) { super(source); this.entity = entity; } public T getEntity() { return entity; } }
@Component public class EntityEventListener { @EventListener public void handleUserCreated(EntityCreatedEvent<User> event) { User user = event.getEntity(); System.out.println("用户创建: " + user.getName()); } @EventListener public void handleOrderCreated(EntityCreatedEvent<Order> event) { Order order = event.getEntity(); System.out.println("订单创建: " + order.getId()); } }
|
条件监听
@Component public class ConditionalListener { @EventListener(condition = "#event.amount > 1000") public void handleBigOrder(OrderCreatedEvent event) { System.out.println("大额订单: " + event.getOrderId()); } }
|
与消息队列对比
| 特性 |
Spring 事件 |
MQ |
| 耦合度 |
应用内解耦 |
系统间解耦 |
| 持久化 |
无 |
有 |
| 可靠性 |
一般 |
高 |
| 分布式 |
不支持 |
支持 |
| 复杂度 |
低 |
高 |
建议:
- 应用内模块通信:Spring 事件
- 跨服务通信:MQ(RabbitMQ、Kafka)
最佳实践
- 事件类命名:以 Event 结尾,过去式(OrderCreatedEvent)
- 事件字段:包含必要上下文,避免过多数据
- 监听器命名:handle + 事件名
- 异步处理:耗时操作使用 @Async
- 事务边界:需要事务保证的使用 @TransactionalEventListener
- 异常处理:配置 ErrorHandler,避免影响其他监听器
总结
Spring 事件机制提供了轻量级的发布-订阅模式:
| 组件 |
作用 |
| ApplicationEvent |
事件基类 |
| ApplicationListener |
监听器接口 |
| @EventListener |
注解方式监听 |
| ApplicationEventPublisher |
事件发布 |
| @TransactionalEventListener |
事务事件 |
合理使用事件机制,可以降低模块耦合,提高代码可维护性。