当前位置:   article > 正文

spring boot(2.4.x之前版本)和spring cloud项目中自动装配的监听执行顺序

spring boot(2.4.x之前版本)和spring cloud项目中自动装配的监听执行顺序

目录

扫描 org.springframework.context.ApplicationListener 指定的类

内置的监听

spring boot 中的监听

spring boot autoconfigure 中的监听

spring boot context 中的监听

将加载的监听进行排序

spring boot 中的监听

spring boot context 中的监听

监听执行

监听加载到 SpringApplicationRunListeners 中

调用 SpringApplicationRunListeners 的 environmentPrepared() 进行监听调用

总结


在前面的文章基础上

https://blog.csdn.net/zlpzlpzyd/article/details/136065211

spring 相关的项目中的代码一直在变,下面以 spring boot 2.3.12.RELEASE 以及对应的 spring cloud Hoxton.SR12 进行说明。

spring boot 在启动时会通过 SpringFactoriesLoader 加载 classpath 下 META-INF/spring.factories 中的对应的类。

扫描 org.springframework.context.ApplicationListener 指定的类

其中监听对应的接口为 ApplicationListener,对应的监听是其实现类实现对应的功能。

内置的监听

spring boot 中的监听

  1. org.springframework.context.ApplicationListener=\
  2. org.springframework.boot.ClearCachesApplicationListener,\
  3. org.springframework.boot.builder.ParentContextCloserApplicationListener,\
  4. org.springframework.boot.cloud.CloudFoundryVcapEnvironmentPostProcessor,\
  5. org.springframework.boot.context.FileEncodingApplicationListener,\
  6. org.springframework.boot.context.config.AnsiOutputApplicationListener,\
  7. org.springframework.boot.context.config.ConfigFileApplicationListener,\
  8. org.springframework.boot.context.config.DelegatingApplicationListener,\
  9. org.springframework.boot.context.logging.ClasspathLoggingApplicationListener,\
  10. org.springframework.boot.context.logging.LoggingApplicationListener,\
  11. org.springframework.boot.liquibase.LiquibaseServiceLocatorApplicationListener

除了 ClearCachesApplicationListener 和 LiquibaseServiceLocatorApplicationListener 都实现了 spring 的接口 Ordered。

spring boot autoconfigure 中的监听

  1. org.springframework.context.ApplicationListener=\
  2. org.springframework.boot.autoconfigure.BackgroundPreinitializer

只有一个 BackgroundPreinitializer,通过注解 @Order 指定了顺序。

spring boot context 中的监听

  1. org.springframework.context.ApplicationListener=\
  2. org.springframework.cloud.bootstrap.BootstrapApplicationListener,\
  3. org.springframework.cloud.bootstrap.LoggingSystemShutdownListener,\
  4. org.springframework.cloud.context.restart.RestartListener

都实现了 spring 的接口 Ordered。

将加载的监听进行排序

在 SpringApplication#getSpringFactoriesInstances() 中通过 AnnotationAwareOrderComparator.sort() 进行处理

其中排序逻辑在父类 OrderComparator 中进行实现。

 

如果当前监听实现了接口 Ordered,则按照对应的编号进行比较,否则直接返回最低优先级,即 Integer.MAX_VALUE。

findOrder() 在子类 AnnotationAwareOrderComparator 中进行重写,用于处理使用注解 @Order 标记的类。

spring boot 中的监听

对应的监听排序如下

  1. CloudFoundryVcapEnvironmentPostProcessor
  2. Integer.MIN_VALUE + 10 - 1
  3. ConfigFileApplicationListener
  4. Integer.MIN_VALUE + 10
  5. AnsiOutputApplicationListener
  6. Integer.MIN_VALUE + 10 + 1
  7. LoggingApplicationListener
  8. Integer.MIN_VALUE + 20
  9. ClasspathLoggingApplicationListener
  10. Integer.MIN_VALUE + 20 + 1
  11. DelegatingApplicationListener
  12. 0
  13. ParentContextCloserApplicationListener
  14. Integer.MAX_VALUE - 10
  15. FileEncodingApplicationListener
  16. Integer.MAX_VALUE
  17. ClearCachesApplicationListener
  18. Integer.MAX_VALUE
  19. LiquibaseServiceLocatorApplicationListener
  20. Integer.MAX_VALUE

实际执行结果

spring boot context 中的监听

对应的监听排序如下

  1. BootstrapApplicationListener
  2. Integer.MIN_VALUE + 5
  3. LoggingSystemShutdownListener
  4. Integer.MIN_VALUE + 5 + 1
  5. RestartListener
  6. 0

结合 spring boot 启动后的顺序如下

  1. BootstrapApplicationListener
  2. Integer.MIN_VALUE + 5
  3. LoggingSystemShutdownListener
  4. Integer.MIN_VALUE + 5 + 1
  5. CloudFoundryVcapEnvironmentPostProcessor
  6. Integer.MIN_VALUE + 10 - 1
  7. ConfigFileApplicationListener
  8. Integer.MIN_VALUE + 10
  9. AnsiOutputApplicationListener
  10. Integer.MIN_VALUE + 10 + 1
  11. LoggingApplicationListener
  12. Integer.MIN_VALUE + 20
  13. ClasspathLoggingApplicationListener
  14. Integer.MIN_VALUE + 20 + 1
  15. DelegatingApplicationListener
  16. 0
  17. RestartListener
  18. 0
  19. ParentContextCloserApplicationListener
  20. Integer.MAX_VALUE - 10
  21. FileEncodingApplicationListener
  22. Integer.MAX_VALUE
  23. ClearCachesApplicationListener
  24. Integer.MAX_VALUE
  25. LiquibaseServiceLocatorApplicationListener
  26. Integer.MAX_VALUE

 实际执行结果

可以看到,引入 spring cloud 组件后,默认执行 BootstrapApplicationListener 中的逻辑加载 bootstrap 相关的配置。

监听执行

监听加载到 SpringApplicationRunListeners 中

上面的监听先加载到了 SpringApplicationRunListeners,内部通过一个集合存储SpringApplicationRunListener 的实现类 EventPublishingRunListener 进行存储以进行后续处理。

通过 SpringApplication#getRunListeners() 进行加载

通过反射创建,构造器参数中传入当前类 SpringApplication。

将 SpringApplication 中加载的监听添加到接口 ApplicationEventMulticaster 的实现类。

SimpleApplicationEventMulticaster 的父类 AbstractApplicationEventMulticaster 的内部类 DefaultListenerRetriever 的变量 applicationListeners 中。

调用 SpringApplicationRunListeners 的 environmentPrepared() 进行监听调用

调用 SpringApplicationRunListeners#environmentPrepared() 间接调用 SpringApplicationRunListener 的 environmentPrepared(),对应的实现类为 EventPublishingRunListener。

执行 SpringApplication#prepareEnvironment()

调用 SimpleApplicationEventMulticaster 的 multicastEvent()

调用 SpringApplicationRunListener#environmentPrepared()

调用 SimpleApplicationEventMulticaster#multicastEvent(),参数为事件 ApplicationEnvironmentPreparedEvent。

循环遍历监听,看是否支持对应的事件

由于排序靠前的监听中 ConfigFileApplicationListener 中引入了 ApplicationEnvironmentPreparedEvent,所以优先处理。

调用了 ConfigFileApplicationListener#onApplicationEvent() 后,处理步骤如下

判断当前事件是否为 ApplicationEnvironmentPreparedEvent 的实例,符合条件,执行后续处理。

加载 classpath 中 META-INF/spring.factories 中指定的 EnvironmentPostProcessor 的实现类。

加载当前类为到 EnvironmentPostProcessor  中并进行排序,ConfigFileApplicationListener 实现了接口 EnvironmentPostProcessor。

执行 EnvironmentPostProcessor#postProcessEnvironment() 进行配置文件加载。

总结

综合上述表述,如果引入了 BootstrapApplicationListener 则优先加载,但是在源码中发现如下

正好对应了我们平时写的 spring boot 启动类,可知,在启动时,如果引入了 spring cloud 组件,会先创建一个子容器来加载对应的配置,然后传递到父容器中进行参数传递,完成参数加载。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/你好赵伟/article/detail/68617
推荐阅读
相关标签
  

闽ICP备14008679号