在 Spring Boot 应用中,监听器(Listeners)是响应应用生命周期事件的核心机制。通过监听器,开发者可以在应用启动、运行或关闭的不同阶段插入自定义逻辑,例如初始化资源、预热缓存或监控状态。本文将深入解析 Spring Boot 启动过程中涉及的监听器类型、事件触发顺序及其实现方式,并提供代码示例与最佳实践。
Spring Boot 的事件体系基于 ApplicationEvent
和 ApplicationListener
,分为 内置系统事件 和 自定义事件 两类 。
Spring Boot 在启动过程中会依次触发以下关键事件:
ApplicationStartingEvent
ApplicationEnvironmentPreparedEvent
ApplicationPreparedEvent
refresh()
方法调用前)。ContextRefreshedEvent
ApplicationStartedEvent
ApplicationRunner
或 CommandLineRunner
。ApplicationReadyEvent
ApplicationFailedEvent
开发者可通过继承 ApplicationEvent
定义业务相关的事件。例如,当订单创建时发布 OrderCreateEvent
,通知其他模块执行后续操作 。
Spring Boot 的监听器调用遵循严格的顺序,具体流程如下 :
注意:
ContextRefreshedEvent
可能因父子容器被多次触发,而ApplicationReadyEvent
仅触发一次,适用于单次初始化任务 。
ApplicationListener
接口java@Component
public class SystemStartupListener implements ApplicationListener<ApplicationReadyEvent> {
@Override
public void onApplicationEvent(ApplicationReadyEvent event) {
System.out.println("== 应用启动完成,执行缓存预热 ==");
}
}
@EventListener
注解java@Component
public class AnnotationBasedListener {
@EventListener
public void handleStartedEvent(ApplicationStartedEvent event) {
System.out.println("== 捕获应用启动事件 ==");
}
}
javapublic class OrderCreateEvent extends ApplicationEvent {
private String orderId;
public OrderCreateEvent(Object source, String orderId) {
super(source);
this.orderId = orderId;
}
}
java@Service
public class OrderService {
@Autowired
private ApplicationEventPublisher eventPublisher;
public void createOrder(Order order) {
// 创建订单逻辑...
eventPublisher.publishEvent(new OrderCreateEvent(this, order.getId()));
}
}
java@Component
public class OrderEventListener {
@EventListener
public void handleOrderEvent(OrderCreateEvent event) {
System.out.println("收到订单事件,ID:" + event.getOrderId());
}
}
通过 @Order
注解定义监听器的优先级:
java@EventListener
@Order(Ordered.HIGHEST_PRECEDENCE) // 最高优先级
public void handleEventFirst(MyEvent event) {
// 优先执行的逻辑
}
结合 @Async
实现非阻塞监听:
java@Configuration
@EnableAsync
public class AsyncConfig { ... }
@EventListener
@Async
public void asyncHandleEvent(MyEvent event) {
// 异步执行耗时操作
}
通过 SpEL 表达式筛选特定事件:
java@EventListener(condition = "#event.orderId.startsWith('VIP')")
public void handleVipOrder(OrderCreateEvent event) {
// 仅处理 VIP 订单
}
ContextRefreshedEvent 被多次触发
ApplicationReadyEvent
保证逻辑仅执行一次 。监听器未生效
@Component
或 @Service
注解。ApplicationEventPublisher
。选择合适的事件类型:
ApplicationReadyEvent
。ContextRefreshedEvent
(注意重复触发问题)。解耦业务逻辑:
通过自定义事件实现模块间通信,避免直接依赖 。
性能优化:
对耗时操作使用异步监听(@Async
),避免阻塞主线程。
通过合理使用监听器,开发者可以更优雅地管理应用生命周期,提升系统的可维护性与扩展性。