-
Spring容器创建前:
-
ApplicationStartingEvent: Spring容器创建前,项目启动时执行;
-
ApplicationEnvironmentPreparedEvent: Spring容器创建前,yml等配置文件加载后执行;
-
Spring容器创建后:
-
ApplicationPreparedEvent: Spring容器创建后,Bean创建前执行;
-
ContextRefreshedEvent: Spring容器创建后,Bean创建后执行;
-
ApplicationStartedEvent: Spring Boot项目启动成功执行;
知识点: 前三种事件发布时, 因为Spring容器还未创建, 所以不能直接使用Spring事件监听器的方式。 需要使用Spring Boot加载事件监听器的方式;
步骤:
- 创建spring.factories文件; resource --> META-INF --> spring.factories
- 自定义事件监听器:
-
public class MyApplicationListener implements ApplicationListener{ @Override public void onApplicationEvent(ApplicationEvent event) { //todo... 做幂等校验,防止业务多次执行; if (event instanceof ApplicationStartingEvent) { System.out.println("Spring容器创建前,项目启动时, 执行=========================="); System.out.println("不可以使用Spring容器中的Bean"); } else if (event instanceof ApplicationEnvironmentPreparedEvent) { System.out.println("Spring容器创建前,yml等配置文件加载后, 执行=================="); System.out.println("不可以使用Spring容器中的Bean"); } else if (event instanceof ApplicationPreparedEvent) { System.out.println("Spring容器创建后,Bean创建前, 执行=========================="); System.out.println("不可以使用Spring容器中的Bean"); } else if (event instanceof ContextRefreshedEvent) { System.out.println("Spring容器创建后,Bean创建后, 执行=========================="); System.out.println("可以使用Spring容器中的Bean"); } else if (event instanceof ApplicationStartedEvent) { System.out.println("Spring Boot项目启动成功, 执行=============================="); System.out.println("可以使用Spring容器中的Bean"); } } }
- 将自定义监听器加入spring.factories文件中:
org.springframework.context.ApplicationListener= \com.example.springbootdemo.listener.MyApplicationListener
- 完成;
启动日志:
特别注意:
需要在onApplicationEvent()方法中,做幂等校验(业务执行前);原因如下两点:
- 服务可能会多节点部署;
- 因为集成Spring Cloud时,run()方法会被执行两次;所以如果项目中集成了Spring Cloud,则事件也会被触发两次;
例如: 使用redis的setnx命令做幂等校验等;