Spring事件机制与监听模式

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;
}

// getter
}

2. 发布事件

@Service
public class OrderService {
@Autowired
private ApplicationEventPublisher eventPublisher;

@Transactional
public void createOrder(OrderRequest request) {
// 1. 创建订单
Order order = orderDao.save(request);

// 2. 发布事件
eventPublisher.publishEvent(
new OrderCreatedEvent(this, order.getId(), order.getAmount())
);

// 3. 其他业务逻辑
}
}

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)

最佳实践

  1. 事件类命名:以 Event 结尾,过去式(OrderCreatedEvent)
  2. 事件字段:包含必要上下文,避免过多数据
  3. 监听器命名:handle + 事件名
  4. 异步处理:耗时操作使用 @Async
  5. 事务边界:需要事务保证的使用 @TransactionalEventListener
  6. 异常处理:配置 ErrorHandler,避免影响其他监听器

总结

Spring 事件机制提供了轻量级的发布-订阅模式:

组件 作用
ApplicationEvent 事件基类
ApplicationListener 监听器接口
@EventListener 注解方式监听
ApplicationEventPublisher 事件发布
@TransactionalEventListener 事务事件

合理使用事件机制,可以降低模块耦合,提高代码可维护性。


   转载规则


《Spring事件机制与监听模式》 小乐 采用 知识共享署名 4.0 国际许可协议 进行许可。
  目录