Spring Boot 事件编程模型
概述
Spring Boot 在启动过程中发布一系列生命周期事件,涵盖从 BootstrapContext 创建到 ApplicationRunner 执行完成的完整流程。结合 Spring Framework 的 @EventListener、@TransactionalEventListener 等注解,开发者可以在特定启动阶段执行自定义逻辑。
本文将详细拆解 Spring Boot 事件的 15 个编程模型细节,涵盖 8 个启动事件的发布时间、监听器注解的高级用法(异步、事务绑定、SpEL 过滤、多事件监听)等核心内容。
本文基于 Spring Boot 3.2.5 + Spring Framework 6.1.6 源码分析。
Spring Framework 通用事件机制可参考 Spring 事件机制。
1. ApplicationStartingEvent 发布时间
ApplicationStartingEvent 是 Spring Boot 启动后发布的第一个事件,发生在 BootstrapContext 创建之后、Environment 准备之前。
public class SpringApplication {
public ConfigurableApplicationContext run(String... args) {
// 1. 创建 BootstrapContext
DefaultBootstrapContext bootstrapContext = createBootstrapContext();
// 2. 发布 ApplicationStartingEvent
listeners.starting(bootstrapContext, this.mainApplicationClass);
// 3. 准备 Environment(此时 Environment 尚未创建)
// ...
}
}listeners.starting() 实现:
class SpringApplicationRunListeners {
void starting(ConfigurableBootstrapContext bootstrapContext, Class<?> mainClass) {
// 创建 ApplicationStartingEvent
ApplicationStartingEvent event = new ApplicationStartingEvent(bootstrapContext, mainClass, args);
// 遍历所有 SpringApplicationRunListener 并调用 starting()
for (SpringApplicationRunListener listener : this.listeners) {
listener.starting(bootstrapContext);
}
// 发布 SpringApplicationEvent
multicastEvent(event);
}
}典型用法:
@Component
public class StartupListener {
@EventListener
public void onStarting(ApplicationStartingEvent event) {
// ⚠️ 注意:此时 Environment 不可用,不能访问 @Value 或配置属性
// 可以执行:设置系统属性、注册 BootstrapRegistry 等
System.setProperty("myapp.startup.time", String.valueOf(System.currentTimeMillis()));
}
}2. ApplicationEnvironmentPreparedEvent 发布时间
ApplicationEnvironmentPreparedEvent 在 Environment 准备完成后发布,此时可以访问所有配置属性。
public class SpringApplication {
public ConfigurableApplicationContext run(String... args) {
// 1. 发布 ApplicationStartingEvent
listeners.starting(bootstrapContext, this.mainApplicationClass);
// 2. 准备 Environment
ConfigurableEnvironment environment = prepareEnvironment(listeners, bootstrapContext, args);
// 3. 在 Environment 准备完成后发布 ApplicationEnvironmentPreparedEvent
listeners.environmentPrepared(bootstrapContext, environment);
}
}listeners.environmentPrepared() 实现:
void environmentPrepared(ConfigurableBootstrapContext bootstrapContext,
ConfigurableEnvironment environment) {
// 创建 ApplicationEnvironmentPreparedEvent
ApplicationEnvironmentPreparedEvent event =
new ApplicationEnvironmentPreparedEvent(bootstrapContext, this.mainApplicationClass, environment);
// 调用所有 SpringApplicationRunListener.environmentPrepared()
for (SpringApplicationRunListener listener : this.listeners) {
listener.environmentPrepared(bootstrapContext, environment);
}
// 发布事件
multicastEvent(event);
}典型用法:
@Component
public class EnvironmentCheckListener {
@EventListener
public void onEnvironmentPrepared(ApplicationEnvironmentPreparedEvent event) {
// Environment 已就绪,可以访问配置属性
ConfigurableEnvironment env = event.getEnvironment();
String activeProfile = StringUtils.arrayToCommaDelimitedString(env.getActiveProfiles());
log.info("Active profiles: {}", activeProfile);
// 可以动态修改 Environment
// env.getPropertySources().addFirst(new MapPropertySource("custom", Map.of(...)));
}
}3. ApplicationContextInitializedEvent 发布时间
ApplicationContextInitializedEvent 在 ApplicationContext 创建完成但尚未 refresh 时发布。
public class SpringApplication {
public ConfigurableApplicationContext run(String... args) {
// ... Environment 准备
// ... 打印 Banner
// ... 创建 ApplicationContext
context = createApplicationContext();
// 应用 ApplicationContextInitializer
applyInitializers(context);
// 发布 ApplicationContextInitializedEvent
listeners.contextPrepared(context);
// 加载 BeanDefinition(注册启动类等)
load(context, sources.toArray(new Object[0]));
// 发布 ApplicationPreparedEvent
listeners.contextLoaded(context);
}
}listeners.contextPrepared():
void contextPrepared(ConfigurableApplicationContext context) {
// 创建 ApplicationContextInitializedEvent
ApplicationContextInitializedEvent event =
new ApplicationContextInitializedEvent(this.bootstrapContext, this.mainApplicationClass, context);
multicastEvent(event);
}此时 ApplicationContext 的状态:
| 状态 | 说明 |
|---|---|
| BeanFactory 已创建 | ✅ 可通过 context.getBeanFactory() 访问 |
ApplicationContextInitializer 已执行 | ✅ initializers.apply() 已完成 |
| BeanDefinition 尚未完全加载 | ⚠️ load() 方法尚未执行 |
| Bean 实例尚未创建 | ❌ refresh() 尚未执行 |
| Environment 已就绪 | ✅ 可访问配置 |
4. ApplicationPreparedEvent 发布时间
ApplicationPreparedEvent 在 BeanDefinition 加载完成后、refresh() 之前发布。
public class SpringApplication {
public ConfigurableApplicationContext run(String... args) {
// ...
applyInitializers(context);
listeners.contextPrepared(context);
// 加载 BeanDefinition(注册启动类、@SpringBootApplication 配置类)
load(context, sources.toArray(new Object[0]));
// 发布 ApplicationPreparedEvent
listeners.contextLoaded(context);
// 刷新 ApplicationContext(创建 Bean 实例)
refreshContext(context);
}
}listeners.contextLoaded():
void contextLoaded(ConfigurableApplicationContext context) {
// 创建 ApplicationPreparedEvent
ApplicationPreparedEvent event =
new ApplicationPreparedEvent(this.bootstrapContext, this.mainApplicationClass, context);
// 注意:这里使用 multicastEvent() → 同步发布
// 监听器在此阶段可以注册额外的 BeanDefinitionPostProcessor
multicastEvent(event);
}典型用法:
@Component
public class BeanDefinitionChecker {
@EventListener
public void onPrepared(ApplicationPreparedEvent event) {
ConfigurableApplicationContext ctx = event.getApplicationContext();
// 可以检查所有已注册的 BeanDefinition
for (String beanName : ctx.getBeanDefinitionNames()) {
log.debug("Bean: {}", beanName);
}
// 可以注册额外的 BeanFactoryPostProcessor
}
}5. ApplicationStartedEvent 发布时间
ApplicationStartedEvent 在 refresh() 完成后、ApplicationRunner 和 CommandLineRunner 执行之前发布。
public class SpringApplication {
public ConfigurableApplicationContext run(String... args) {
// ...
refreshContext(context); // 创建所有 Bean
afterRefresh(context, args); // 空方法,供子类覆盖
// 发布 ApplicationStartedEvent
listeners.started(context);
// 执行 ApplicationRunner / CommandLineRunner
callRunners(context, args);
// 发布 ApplicationReadyEvent
listeners.ready(context);
}
}listeners.started():
void started(ConfigurableApplicationContext context) {
// 创建 ApplicationStartedEvent
ApplicationStartedEvent event =
new ApplicationStartedEvent(this.bootstrapContext, this.mainApplicationClass, context);
multicastEvent(event);
}此时 ApplicationContext 的状态:
| 状态 | 说明 |
|---|---|
refresh() 完成 | ✅ 所有单例 Bean 已创建 |
所有 @PostConstruct 已执行 | ✅ |
SmartInitializingSingleton 已回调 | ✅ |
| ApplicationRunner 尚未执行 | ❌ |
| Web 服务器已启动 | ✅(Web 应用) |
6. AvailabilityChangeEvent 发布时间
AvailabilityChangeEvent 在应用可用状态变更时发布。Spring Boot 定义了两种状态:
LivenessState(存活状态):应用是否正在运行ReadinessState(就绪状态):应用是否准备好接受请求
// 在启动过程中多次发布
public class SpringApplication {
public ConfigurableApplicationContext run(String... args) {
// ...
refreshContext(context);
afterRefresh(context, args);
// 1. 发布 ApplicationStartedEvent + LivenessState.CORRECT
listeners.started(context);
// 此时内部会发布 AvailabilityChangeEvent(LivenessState.CORRECT)
callRunners(context, args);
// 2. 发布 ApplicationReadyEvent + ReadinessState.ACCEPTING_TRAFFIC
listeners.ready(context);
// 此时内部会发布 AvailabilityChangeEvent(ReadinessState.ACCEPTING_TRAFFIC)
}
}AvailabilityChangeEvent 源码:
public class AvailabilityChangeEvent extends ApplicationEvent {
private final State state;
public AvailabilityChangeEvent(Object source, State state) {
super(source);
this.state = state;
}
public State getState() {
return this.state;
}
// 便捷发布方法
public static void publish(ApplicationContext context, State state) {
context.publishEvent(new AvailabilityChangeEvent(context, state));
}
}监听示例:
@Component
public class AvailabilityListener {
@EventListener
public void onAvailabilityChange(AvailabilityChangeEvent<ReadinessState> event) {
ReadinessState state = event.getState();
if (state == ReadinessState.ACCEPTING_TRAFFIC) {
log.info("应用已就绪,开始接受流量");
// 通知注册中心(如 Nacos、Eureka)
}
}
}状态变更场景:
| 场景 | LivenessState | ReadinessState |
|---|---|---|
| 启动中 | — | REFUSING_TRAFFIC |
| 启动完成 | CORRECT | ACCEPTING_TRAFFIC |
| 健康检查失败 | BROKEN | — |
| 优雅关闭 | — | REFUSING_TRAFFIC |
7. ApplicationReadyEvent 发布时间
ApplicationReadyEvent 在所有 ApplicationRunner 和 CommandLineRunner 执行完成后发布,标识应用已完全就绪。
public class SpringApplication {
public ConfigurableApplicationContext run(String... args) {
// ...
refreshContext(context);
afterRefresh(context, args);
listeners.started(context); // ① 启动事件
callRunners(context, args); // ② 执行 Runner
listeners.ready(context); // ③ 就绪事件
}
}listeners.ready():
void ready(ConfigurableApplicationContext context) {
// 创建 ApplicationReadyEvent
ApplicationReadyEvent event =
new ApplicationReadyEvent(this.bootstrapContext, this.mainApplicationClass, context);
multicastEvent(event);
// 顺便发布 ReadinessState.ACCEPTING_TRAFFIC
AvailabilityChangeEvent.publish(context, ReadinessState.ACCEPTING_TRAFFIC);
}典型用法:
@Component
public class PostStartupTask {
@EventListener
public void onReady(ApplicationReadyEvent event) {
// 应用已完全就绪,执行启动后任务
// 预热缓存
productCache.warmUp();
// 发送启动通知
alertService.sendStartupNotification();
// 连接 WebSocket
wsClient.connect();
}
}8. ApplicationFailedEvent 发布时间
当启动失败时,Spring Boot 发布 ApplicationFailedEvent,包含异常信息。
public class SpringApplication {
public ConfigurableApplicationContext run(String... args) {
try {
// ... 整个启动流程
return context;
} catch (Throwable ex) {
// 发布 ApplicationFailedEvent
handleRunFailure(context, ex, listeners);
throw new IllegalStateException("Failed to execute application", ex);
}
}
private void handleRunFailure(ConfigurableApplicationContext context, Throwable exception,
SpringApplicationRunListeners listeners) {
// 捕获所有注册的 FailureAnalyzer
List<FailureAnalyzer> analyzers = FailureAnalyzers.get();
// 发布 ApplicationFailedEvent
if (context != null) {
listeners.failed(context, exception);
} else {
// context 未创建时也要发布
listeners.failed(new DefaultBootstrapContext(), exception);
}
}
}ApplicationFailedEvent:
public class ApplicationFailedEvent extends SpringApplicationEvent {
private final SpringApplication application;
private final String[] args;
private final ConfigurableApplicationContext context;
private final Throwable exception; // 启动异常
public Throwable getException() {
return this.exception;
}
}典型用法:
@Component
public class StartupFailureHandler {
@EventListener
public void onFailure(ApplicationFailedEvent event) {
Throwable ex = event.getException();
log.error("启动失败: {}", ex.getMessage(), ex);
// 发送告警
alertService.sendAlert("应用启动失败", ex);
// 清理资源
// 记录错误详情到日志文件
}
}9. @EventListener 的异步支持
@EventListener 结合 @Async 可以实现异步事件处理,避免阻塞发布者线程。
@Component
public class AsyncEventListener {
@Async // 异步执行
@EventListener
public void handleOrderCreated(OrderCreatedEvent event) {
// 在独立线程中执行,不阻塞发布者
// 适合:发送通知、记录审计日志、触发外部 API 等
notificationService.sendEmail(event.getOrderId());
}
}配置要求:
@Configuration
@EnableAsync // 启用异步支持
public class AsyncConfig implements AsyncConfigurer {
@Override
public Executor getAsyncExecutor() {
// 自定义线程池
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setCorePoolSize(5);
executor.setMaxPoolSize(10);
executor.setQueueCapacity(100);
executor.setThreadNamePrefix("event-");
executor.initialize();
return executor;
}
}SimpleApplicationEventMulticaster 的异步实现:
public class SimpleApplicationEventMulticaster extends AbstractApplicationEventMulticaster {
private Executor taskExecutor; // 默认为 null(同步执行)
@Override
public void multicastEvent(ApplicationEvent event, ResolvableType eventType) {
ResolvableType type = (eventType != null) ? eventType : resolveDefaultEventType(event);
Executor executor = getTaskExecutor(); // 获取 Executor
for (ApplicationListener<?> listener : getApplicationListeners(event, type)) {
if (executor != null) {
// 异步执行
executor.execute(() -> invokeListener(listener, event));
} else {
// 同步执行
invokeListener(listener, event);
}
}
}
}同步 vs 异步对比:
| 特性 | 同步 @EventListener | 异步 @EventListener + @Async |
|---|---|---|
| 执行线程 | 发布者线程 | 独立线程池 |
| 顺序性 | 按注册顺序同步执行 | 无序 |
| 异常影响 | 异常传播到发布者 | 异常不影响发布者 |
| 事务 | 参与发布者事务 | 独立事务 |
| 适用场景 | 数据一致性要求高 | 非关键路径通知任务 |
10. @TransactionalEventListener 的 5 个 phase
@TransactionalEventListener 提供了事务边界事件监听,支持在不同事务阶段触发。
@Target({ElementType.METHOD, ElementType.ANNOTATION_TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@EventListener
public @interface TransactionalEventListener {
// 事务阶段
TransactionPhase phase() default TransactionPhase.AFTER_COMMIT;
// 如果没有事务,是否仍然执行
boolean fallbackExecution() default false;
// 事件类(@EventListener 的 classes 属性)
@AliasFor(annotation = EventListener.class, attribute = "classes")
Class<?>[] value() default {};
@AliasFor(annotation = EventListener.class, attribute = "classes")
Class<?>[] classes() default {};
}5 个 TransactionPhase(实际 4 个枚举值,但从语义上分解为 5 种行为):
public enum TransactionPhase {
BEFORE_COMMIT, // 事务提交前执行(在 flush 之后,commit 之前)
AFTER_COMMIT, // 事务提交成功后执行(默认)
AFTER_ROLLBACK, // 事务回滚后执行
AFTER_COMPLETION // 事务完成后执行(无论是提交还是回滚)
}使用示例:
@Component
public class OrderEventListener {
@TransactionalEventListener(phase = TransactionPhase.AFTER_COMMIT)
public void onOrderCreated(OrderCreatedEvent event) {
// 事务提交成功后发送消息
// 如果事务回滚,此方法不会执行
messageQueue.send("order.created", event.getOrderId());
}
@TransactionalEventListener(phase = TransactionPhase.AFTER_ROLLBACK)
public void onOrderFailed(OrderCreatedEvent event) {
// 事务回滚时处理
log.warn("订单创建失败,已回滚: {}", event.getOrderId());
inventoryService.compensate(event.getOrderId());
}
@TransactionalEventListener(phase = TransactionPhase.AFTER_COMPLETION)
public void onOrderCompleted(OrderCreatedEvent event) {
// 事务完成(无论提交或回滚)记录审计日志
auditLog.record("ORDER_CREATE", event.getOrderId());
}
}各个 phase 的执行时机:
@Transactional 方法开始
↓
业务逻辑执行
↓
@TransactionalEventListener(BEFORE_COMMIT) ← flush 之后、commit 之前
↓
事务提交(commit / rollback)
↓
├── 提交成功 → @TransactionalEventListener(AFTER_COMMIT) ← 发送 MQ、通知
└── 回滚 → @TransactionalEventListener(AFTER_ROLLBACK) ← 补偿操作
↓
@TransactionalEventListener(AFTER_COMPLETION) ← 无论成功与否,记录审计日志TransactionSynchronizationManager 注册事务同步:
// TransactionalEventListenerFactory 创建 TransactionalApplicationListener
// 内部调用 TransactionSynchronizationManager.registerSynchronization()
// 将监听器注册为事务同步回调
class TransactionalApplicationListenerMethodAdapter {
public void onApplicationEvent(ApplicationEvent event) {
if (TransactionSynchronizationManager.isSynchronizationActive()) {
// 注册事务同步回调
TransactionSynchronizationManager.registerSynchronization(
new TransactionalEventSynchronization<>(event, this.phase));
} else if (this.fallbackExecution) {
// 没有事务时,如果 fallbackExecution=true 则直接执行
processEvent(event);
}
}
}11. ApplicationEventMulticaster 的选择
Spring 支持两种 ApplicationEventMulticaster 实现,选择策略如下:
// AbstractApplicationContext.initApplicationEventMulticaster()
// 在 refresh() 的 initMessageSource() 之后调用
protected void initApplicationEventMulticaster() {
ConfigurableListableBeanFactory beanFactory = getBeanFactory();
// 1. 先检查是否有用户自定义的 multicaster
if (beanFactory.containsLocalBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME)) {
this.applicationEventMulticaster =
beanFactory.getBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, ApplicationEventMulticaster.class);
}
else {
// 2. 默认使用 SimpleApplicationEventMulticaster
this.applicationEventMulticaster = new SimpleApplicationEventMulticaster(beanFactory);
beanFactory.registerSingleton(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, this.applicationEventMulticaster);
}
}两种实现对比:
| 特性 | SimpleApplicationEventMulticaster(默认) | 自定义 ApplicationEventMulticaster |
|---|---|---|
| 执行方式 | 同步(默认)/ 可设 Executor | 完全自定义 |
| 异常处理 | 默认抛出异常,可设 ErrorHandler | 自定义 |
| 创建方式 | Spring Boot 自动注册 | 用户定义 @Bean 覆盖 |
| 适用场景 | 绝大多数场景 | 需要特殊路由或错误处理 |
自定义异步 Multicaster:
@Configuration
public class EventConfig {
@Bean(name = "applicationEventMulticaster")
public ApplicationEventMulticaster applicationEventMulticaster() {
SimpleApplicationEventMulticaster multicaster = new SimpleApplicationEventMulticaster();
// 设置异步执行器(所有事件异步)
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setCorePoolSize(5);
executor.setMaxPoolSize(10);
executor.setThreadNamePrefix("event-");
executor.initialize();
multicaster.setTaskExecutor(executor);
// 设置错误处理器(避免异步事件异常丢失)
multicaster.setErrorHandler(throwable -> {
log.error("事件处理异常", throwable);
});
return multicaster;
}
}12. PayloadApplicationEvent 的泛型
Spring 4.2+ 支持直接发布任意 POJO 作为事件,ApplicationEventPublisher.publishEvent(Object) 会自动包装为 PayloadApplicationEvent。
// 发布任意 POJO(不需要继承 ApplicationEvent)
@Service
public class OrderService {
@Autowired
private ApplicationEventPublisher publisher;
public void createOrder(Order order) {
// 直接发布 Order 对象
publisher.publishEvent(order);
// 等价于:
// publisher.publishEvent(new PayloadApplicationEvent<>(this, order));
}
}PayloadApplicationEvent 源码:
public class PayloadApplicationEvent<T> extends ApplicationEvent implements ResolvableTypeProvider {
private final T payload;
public PayloadApplicationEvent(Object source, T payload) {
super(source);
this.payload = payload;
}
public T getPayload() {
return this.payload;
}
@Override
public ResolvableType getResolvableType() {
// 返回带泛型参数的类型,便于监听器按泛型类型匹配
return ResolvableType.forClassWithGenerics(getClass(),
ResolvableType.forInstance(this.payload));
}
}监听 POJO 事件:
@Component
public class OrderEventListener {
// 监听 POJO 类型的 PayloadApplicationEvent
@EventListener
public void handleOrderEvent(Order order) {
// 直接使用 POJO 类型,不需要包装事件类
log.info("收到订单事件: {}", order.getId());
}
// 也可以监听 PayloadApplicationEvent 本身
@EventListener
public void handlePayload(PayloadApplicationEvent<Order> event) {
Order order = event.getPayload();
// ...
}
}事件匹配机制:
publisher.publishEvent(orderInstance)
↓
AbstractApplicationContext.publishEvent(Object)
↓
判断 event 是否为 ApplicationEvent 的子类
↓
不是 → 包装为 PayloadApplicationEvent<>(this, orderInstance)
↓
委托给 multicaster.multicastEvent()
↓
根据 ResolvableType 匹配监听器参数类型13. @EventListener 的 SpEL 条件
@EventListener 的 condition 属性支持 SpEL 表达式,可以基于事件属性进行条件过滤。
@Component
public class ConditionalEventListener {
@EventListener(condition = "#event.status == 'SUCCESS'")
public void onSuccess(OrderProcessedEvent event) {
// 只在 order.status == "SUCCESS" 时执行
log.info("订单处理成功: {}", event.getOrderId());
}
@EventListener(condition = "#event.status == 'FAILED'")
public void onFailure(OrderProcessedEvent event) {
// 只在 order.status == "FAILED" 时执行
log.warn("订单处理失败: {}", event.getOrderId());
}
@EventListener(condition = "#event.amount > 10000")
public void onLargeAmount(OrderProcessedEvent event) {
// 金额大于 10000 时执行
auditService.flagForReview(event.getOrderId());
}
}SpEL 上下文中可用的变量:
| 变量 | 说明 |
|---|---|
#event | 事件对象(方法参数名) |
#root.event | 事件对象 |
#root.args | 方法参数数组 |
复杂条件:
@EventListener(condition = "#event.status == 'SUCCESS' && #event.amount > 5000")
public void onLargeSuccess(OrderProcessedEvent event) {
// 多个条件组合
}
@EventListener(condition = "#event.orderType.name() == 'VIP'")
public void onVipOrder(OrderProcessedEvent event) {
// 使用枚举
}SpEL 条件评估实现:
class ApplicationListenerMethodAdapter {
@Nullable
private final String condition; // SpEL 表达式
public void onApplicationEvent(ApplicationEvent event) {
// 评估 SpEL 条件
if (this.condition != null) {
StandardEvaluationContext context = new StandardEvaluationContext();
context.setRootObject(event);
context.setVariable("event", event);
// ...
Boolean result = this.evaluator.condition(this.condition, context);
if (!Boolean.TRUE.equals(result)) {
return; // 条件不满足,跳过
}
}
// 执行监听方法
processEvent(event);
}
}14. @EventListener 的 id 与 classes 属性
@EventListener 支持监听多个事件类型,以及为监听器指定唯一标识。
@Component
public class MultiEventListener {
// 监听多个事件类型
@EventListener({OrderCreatedEvent.class, OrderUpdatedEvent.class, OrderCancelledEvent.class})
public void onOrderChanged(Object event) {
if (event instanceof OrderCreatedEvent e) {
log.info("订单创建: {}", e.getOrderId());
} else if (event instanceof OrderUpdatedEvent e) {
log.info("订单更新: {}", e.getOrderId());
} else if (event instanceof OrderCancelledEvent e) {
log.info("订单取消: {}", e.getOrderId());
}
}
// 指定监听器 id(用于管理)
@EventListener(id = "auditListener", classes = OrderEvent.class)
public void onOrderEvent(OrderEvent event) {
auditLog.record(event);
}
}@EventListener 注解属性:
@Target({ElementType.METHOD, ElementType.ANNOTATION_TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface EventListener {
// 监听器唯一标识(用于管理和排序)
@AliasFor("classes")
Class<?>[] value() default {};
// 监听的事件类数组
@AliasFor("value")
Class<?>[] classes() default {};
// SpEL 条件表达式
String condition() default "";
// 监听器唯一 ID
String id() default "";
}监听器排序:
@Component
public class OrderedListeners {
@EventListener
@Order(1) // 数字越小优先级越高
public void firstHandler(OrderCreatedEvent event) {
log.info("第一个处理");
}
@EventListener
@Order(2)
public void secondHandler(OrderCreatedEvent event) {
log.info("第二个处理");
}
}15. ApplicationEvent 的继承关系
Spring Boot 启动事件的完整继承体系:
java.util.EventObject
└── ApplicationEvent (org.springframework.context)
├── SpringApplicationEvent (org.springframework.boot.context.event)
│ ├── ApplicationStartingEvent ← 启动开始
│ ├── ApplicationEnvironmentPreparedEvent ← 环境就绪
│ ├── ApplicationContextInitializedEvent ← 上下文创建
│ ├── ApplicationPreparedEvent ← BeanDefinition 加载
│ ├── ApplicationStartedEvent ← refresh 完成
│ ├── ApplicationReadyEvent ← Runner 执行完
│ └── ApplicationFailedEvent ← 启动失败
│
├── AvailabilityChangeEvent (org.springframework.boot.availability)
│ └── 由 SpringApplication 在 started/ready 时发布
│
├── PayloadApplicationEvent<T> (org.springframework.context)
│ └── 包装任意 POJO 事件
│
└── RequestHandledEvent (org.springframework.web.context)
└── ServletRequestHandledEvent完整的启动事件时间线:
时间 →→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→
① ApplicationStartingEvent BootstrapContext 创建后
↓
② ApplicationEnvironmentPreparedEvent Environment 准备后
↓
③ ApplicationContextInitializedEvent ApplicationContext 创建后
↓
④ ApplicationPreparedEvent BeanDefinition 加载后
↓ refresh()
⑤ ApplicationStartedEvent 所有 Bean 创建后
↓
AvailabilityChangeEvent(LivenessState.CORRECT) 存活就绪
↓ callRunners()
AvailabilityChangeEvent(ReadinessState.ACCEPTING_TRAFFIC) 流量就绪
↓
⑥ ApplicationReadyEvent 完全就绪
↓
⑦ ApplicationFailedEvent (仅在启动失败时)总结
Spring Boot 事件编程模型的 15 个细节点总结如下:
| # | 细节点 | 核心类/时机 |
|---|---|---|
| ① | ApplicationStartingEvent 发布时间 | BootstrapContext 创建后,Environment 准备前 |
| ② | ApplicationEnvironmentPreparedEvent 发布时间 | Environment 准备完成后 |
| ③ | ApplicationContextInitializedEvent 发布时间 | ApplicationContext 创建完成后 |
| ④ | ApplicationPreparedEvent 发布时间 | BeanDefinition 加载完成后,refresh() 前 |
| ⑤ | ApplicationStartedEvent 发布时间 | refresh() 完成后,runners 执行前 |
| ⑥ | AvailabilityChangeEvent 发布时间 | LivenessState / ReadinessState 变更时 |
| ⑦ | ApplicationReadyEvent 发布时间 | runners 执行完成后 |
| ⑧ | ApplicationFailedEvent 发布时间 | 启动异常时 |
| ⑨ | @EventListener 的异步支持 | @Async + @EventListener 组合 + SimpleApplicationEventMulticaster.setTaskExecutor() |
| ⑩ | @TransactionalEventListener 的 phase | BEFORE_COMMIT / AFTER_COMMIT / AFTER_ROLLBACK / AFTER_COMPLETION |
| ⑪ | ApplicationEventMulticaster 的选择 | SimpleApplicationEventMulticaster(默认)vs 自定义 |
| ⑫ | PayloadApplicationEvent 的泛型 | 任意 POJO → publishEvent(obj) 自动包装 |
| ⑬ | @EventListener 的 SpEL 条件 | condition = "#event.status == 'SUCCESS'" |
| ⑭ | @EventListener 的 id 与 classes 属性 | 监听多个事件类、设置监听器 ID |
| ⑮ | ApplicationEvent 的继承关系 | SpringApplicationEvent → 7 个启动事件 |