Spring事件监听初始化

Spring/SpringBoot 上下文事件

  1. @Slf4j
  2. @SpringBootApplication
  3. public class DemoApplication {
  4. public static void main(String[] args) {
  5. SpringApplication springApplication = new SpringApplication(DemoApplication.class);
  6. initEventListeners(springApplication);
  7. springApplication.run(args);
  8. }
  9. private static void initEventListeners(SpringApplication application) {
  10. application.addListeners(
  11. // log不输出,out可以输出
  12. (ApplicationStartingEvent event) -> System.out.println(event.getClass().getName()),
  13. (ApplicationEnvironmentPreparedEvent event) -> logEvent(event),
  14. (ApplicationContextInitializedEvent event) -> logEvent(event),
  15. (ApplicationPreparedEvent event) -> logEvent(event),
  16. (ContextRefreshedEvent event) -> logEvent(event),
  17. (ApplicationStartedEvent event) -> logEvent(event),
  18. (ApplicationReadyEvent event) -> logEvent(event),
  19. (ApplicationFailedEvent event) -> logEvent(event),
  20. (ContextClosedEvent event) -> logEvent(event),
  21. // 未输出
  22. (ContextStartedEvent event) -> logEvent(event),
  23. (ContextStoppedEvent event) -> logEvent(event)
  24. );
  25. }
  26. private static void logEvent(ApplicationEvent event) {
  27. log.info("# {} ###############", event.getClass().getSimpleName());
  28. }
  29. }

输出顺序:

  1. ApplicationStartingEvent
  2. ApplicationEnvironmentPreparedEvent
  3. ApplicationContextInitializedEvent
  4. ApplicationPreparedEvent
  5. ContextRefreshedEvent
  6. ApplicationStartedEvent
  7. ApplicationReadyEvent
  8. ApplicationFailedEvent/ContextClosedEvent

类结构:
SpringBoot 启动前后的初始化 - 图1

Spring 内置事件

  1. ContextRefreshEvent: ApplicationContext 容器初始化或刷新触发该事件。此处的初始化是指,所有Bean 被成功装载后处理 Bean 被检测并激发,所有 Singleton Bean 被预实例化,ApplicationContext 容器已就绪可用。
  2. ContextStartedEvent::当使用 ConfigurableApplicationContext(ApplicationContext的子接口) 接口的 start() 方法启动 ApplicationContext 容器时触发该事件。容器管理生命周期的 Bean 实例将获得一个指定的启动信号,这在经常需要停止后重新启动的场合比较常见。
  3. ContextClosedEvent:当使用 ConfigurableApplicationContext 接口的 close() 方法关闭ApplicationContext 容器时触发该事件。
  4. ContextStoppedEvent:当使用 ConfigurableApplicationContext 接口的 stop() 方法使ApplicationContext 停止时触发该事件。此处的“停止”意味着容器管理生命周期的 Bean 实例将获得一个指定的停止信号,被停止的 Spring 容器可在此调用 start() 方法重新启动。
  5. RequestHandledEvent:Web 相关的事件,只能运用于使用 DispatcherServlet 的 Web 运用。在使用Spring 作为前端的 MVC 控制器时,当 Spring 处理用户请求结束后,系统会自动触发该事件。

Spring的这种事件模型其实就是标准的观察者设计模式。

SpringBoot 内置事件

  1. ApplicationStartingEvent: 在运行开始时但在任何处理之前发送 ApplicationStartingEvent ,但监听器和初始化程序的注册除外。
  2. ApplicationEnvironmentPreparedEvent:当在上下文中使用的 Environment 已知但在创建上下文之前发送 ApplicationEnvironmentPreparedEvent
  3. ApplicationContextInitializedEvent
  4. ApplicationPreparedEvent: 在开始刷新之前,bean 定义被加载之后发送 ApplicationPreparedEvent
  5. ApplicationStartedEvent:在刷新上下文之后但在调用任何应用程序和命令行运行程序之前发送 ApplicationStartedEvent 。
  6. ApplicationReadyEvent:在调用任何应用程序和命令行运行程序后发送 ApplicationReadyEvent 。它表示应用程序已准备好为请求提供服务。
  7. ApplicationFailedEvent:如果启动时发生异常,则发送 ApplicationFailedEvent 。

    说明

    SpringBoot 环境下,执行 ApplicationStartedEvent 事件,并不会执行ContextStartedEvent(在SpringBoot 下可能被忽略)

    容器完成后的初始化

    CommandLineRunner、ApplicationRunner

  8. ApplicationRunnerCommandLineRunner的执行在 ApplicationReadyEvent之后

  9. 如果有多个,可以使用 @Order 注解设定运行顺序