深圳做电商网站,什么网站可以做动图,八桂职教网技能大赛2024,百度推广seo软件驾驭 Spring Boot 事件机制#xff1a;8 个内置事件 自定义扩展实战在 Spring Boot 应用的完整生命周期中#xff0c;框架为我们预埋了 8 个关键事件#xff08;Application-level Context-level#xff09;。 理解并善用这些事件#xff0c;可以在“不侵入框架、…驾驭 Spring Boot 事件机制8 个内置事件 自定义扩展实战在 Spring Boot 应用的完整生命周期中框架为我们预埋了 8 个关键事件Application-level Context-level。 理解并善用这些事件可以在“不侵入框架、不修改源码”的前提下注入个性化初始化、监控、清理逻辑。 本文将带你从 0 到 1 掌握事件机制并给出可直接落地的代码模板。一、为什么需要事件机制场景传统做法事件机制优势启动时加载字典缓存CommandLineRunner无侵入、可插拔、可排序优雅停机PreDestroy与 Spring 生命周期同步确保资源释放顺序多模块解耦直接调用发布-订阅模块间零依赖
二、Spring Boot 8 大内置事件一览事件触发阶段典型用途监听器注册方式ApplicationStartingEventrun() 刚被调用日志系统尚未初始化极早期检查、初始化日志桥接SpringApplication.addListeners(...)ApplicationEnvironmentPreparedEventEnvironment 已就绪但 BeanDefinition 尚未加载动态修改配置源、激活 Profile同上ApplicationContextInitializedEventApplicationContext 已创建但尚未 refresh注册 BeanFactoryPostProcessor同上ApplicationPreparedEventBeanDefinition 已加载Environment 可用读取配置、校验必备属性同上ContextRefreshedEventrefresh() 完成所有单例已实例化缓存预热、注册监控ComponentServletWebServerInitializedEvent内嵌容器端口已打开获取运行时端口、注册服务发现ComponentApplicationStartedEvent容器已启动所有 CommandLineRunner 已执行发送启动成功指标ComponentApplicationReadyEvent同上额外保证所有应用初始化器已完成开启流量、发送通知Component
Spring Boot 2.x 之后新增 ApplicationStartingEvent、ApplicationStartedEvent 等旧版只有 5 个核心事件。三、实战监听 4 个高频事件
1. 启动早期动态注入配置
public class EarlyEnvInjector implements ApplicationListenerApplicationEnvironmentPreparedEvent {Overridepublic void onApplicationEvent(ApplicationEnvironmentPreparedEvent event) {ConfigurableEnvironment env event.getEnvironment();// 模拟从 Apollo/Nacos 拉取最新配置MapString, Object override Map.of(spring.datasource.url, jdbc:mysql://newHost/dev);env.getPropertySources().addFirst(new MapPropertySource(dynamic, override));}
}注册方式在 main 方法里
SpringApplication app new SpringApplication(DemoApp.class);
app.addListeners(new EarlyEnvInjector());
app.run(args);2. 容器刷新后预热缓存
Component
public class CacheWarmer implements ApplicationListenerContextRefreshedEvent {Overridepublic void onApplicationEvent(ContextRefreshedEvent event) {if (event.getApplicationContext().getParent() null) { // 防止重复执行DictCache.loadAll();}}
}3. 优雅停机前释放资源
Component
public class GracefulShutdown implements ApplicationListenerContextClosedEvent {private final ExecutorService pool Executors.newFixedThreadPool(10);Overridepublic void onApplicationEvent(ContextClosedEvent event) {pool.shutdown();try {if (!pool.awaitTermination(10, TimeUnit.SECONDS)) {pool.shutdownNow();}} catch (InterruptedException e) {pool.shutdownNow();}}
}4. 启动完毕发送监控告警
Component
public class StartupReporter implements ApplicationListenerApplicationReadyEvent {Overridepublic void onApplicationEvent(ApplicationReadyEvent event) {InetAddress host InetAddress.getLocalHost();String port event.getApplicationContext().getEnvironment().getProperty(local.server.port);DingTalk.send(✅ 服务启动完成: host.getHostAddress() : port);}
}四、扩展自定义业务事件
1. 定义领域事件
public class OrderPaidEvent extends ApplicationEvent {private final Long orderId;private final BigDecimal amount;public OrderPaidEvent(Object source, Long orderId, BigDecimal amount) {super(source);this.orderId orderId;this.amount amount;}// getters ...
}2. 发布事件
Service
RequiredArgsConstructor
public class OrderService {private final ApplicationEventPublisher publisher;public void pay(Long orderId) {// 业务逻辑...publisher.publishEvent(new OrderPaidEvent(this, orderId, BigDecimal.valueOf(99)));}
}3. 多监听器异步消费
Component
public class InvoiceGenerator {EventListenerAsync(invoiceTaskExecutor) // 线程池隔离public void onOrderPaid(OrderPaidEvent event) {// 生成电子发票...}
}五、最佳实践清单
顺序控制使用 Order 或实现 Ordered 接口。线程安全早期事件如 ApplicationStartingEvent发布时Bean 尚未实例化此时注册逻辑需避免依赖 IOC 容器。条件化监听ConditionalOnProperty 或 Environment 判断避免在测试环境触发线上逻辑。异步场景Async 自定义线程池防止阻塞主流程。可观测性通过 Micrometer 记录事件处理耗时及时发现慢监听器。六、小结目标推荐事件动态修改配置ApplicationEnvironmentPreparedEvent容器初始化后一次性任务ContextRefreshedEvent优雅停机ContextClosedEvent服务启动成功通知ApplicationReadyEvent业务解耦自定义 ApplicationEvent