SpringBoot 项目启动后监听器执行操作:ContextRefreshEvent
一 Spring boot运行时,会依次发送以下事件
1. ApplicationStartingEvent
2. ApplicationEnvironmentPreparedEvent:当Environment已经准备好,在context 创建前
3. ApplicationContextInitializedEvent:在ApplicationContext 创建和ApplicationContextInitializer都被调用后,但是bean definition没有被加载前
4. ApplicationPreparedEvent:bean definition已经加载,但是没有refresh
5. ApplicationStartedEvent: context 已经被refresh, 但是application 和command-line 的runner都没有被调用
6. AvailabilityChangeEvent
7. ApplicationReadyEvent: application 和command-line 的runner都被调用后触发
8. AvailabilityChangeEvent
9. ApplicationFailedEvent: 启动失败触发
另外,会在 ApplicationPreparedEvent 之后和 ApplicationStartedEvent 之前发送 ContextRefreshedEvent 事件
二 项目启动后需要执行某个操作
1. 实现 ApplicationListener<E extends ApplicationEvent>接口
2. ApplicationEvent 的子类可以是 ApplicationReadyEvent 或者 ContextRefreshedEvent
3. ApplicationReadyEvent 的示例
@Component @Slf4j public class ApplicationInit implements ApplicationListener<ApplicationReadyEvent> { // 项目启动后预热JSONObject @Override public void onApplicationEvent(ApplicationReadyEvent applicationReadyEvent) { UserInfo userInfo = new UserInfo(); userInfo.setId(123L); userInfo.setChannel("hello"); String userJson = JSON.toJSONString(userInfo); JSONObject.parseObject(userJson, UserInfo.class); } }
三 ContextRefreshedEvent 多次执行的问题
1. web应用会出现父子容器,这样就会触发两次
2. 解决方法:ApplicationListener<ContextRefreshedEvent> 应该和 ApplicationContext 一对一
@Order @Component @Slf4j public class ApplicationInit implements ApplicationListener<ContextRefreshedEvent> { @Override public void onApplicationEvent(ContextRefreshedEvent event) { // SpringBoot 项目区启动后,监听器执行对应事件的逻辑 UserInfo userInfo = new UserInfo(); userInfo.setId(123L); userInfo.setChannel("hello"); String userJson = JSON.toJSONString(userInfo); JSONObject.parseObject(userJson, UserInfo.class); } }