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

 

posted @ 2024-06-21 16:18  菜鸟的奋斗之路  阅读(28)  评论(0编辑  收藏  举报