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(2.4.x之前版本)和spring cloud项目中自动装配的监听执行顺序_第1张图片

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

内置的监听

spring boot 中的监听

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

org.springframework.context.ApplicationListener=\
org.springframework.boot.ClearCachesApplicationListener,\
org.springframework.boot.builder.ParentContextCloserApplicationListener,\
org.springframework.boot.cloud.CloudFoundryVcapEnvironmentPostProcessor,\
org.springframework.boot.context.FileEncodingApplicationListener,\
org.springframework.boot.context.config.AnsiOutputApplicationListener,\
org.springframework.boot.context.config.ConfigFileApplicationListener,\
org.springframework.boot.context.config.DelegatingApplicationListener,\
org.springframework.boot.context.logging.ClasspathLoggingApplicationListener,\
org.springframework.boot.context.logging.LoggingApplicationListener,\
org.springframework.boot.liquibase.LiquibaseServiceLocatorApplicationListener

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

spring boot autoconfigure 中的监听

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

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

spring boot context 中的监听

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

org.springframework.context.ApplicationListener=\
org.springframework.cloud.bootstrap.BootstrapApplicationListener,\
org.springframework.cloud.bootstrap.LoggingSystemShutdownListener,\
org.springframework.cloud.context.restart.RestartListener

都实现了 spring 的接口 Ordered。

将加载的监听进行排序

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

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

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

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

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

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

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

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

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

spring boot 中的监听

对应的监听排序如下

CloudFoundryVcapEnvironmentPostProcessor
Integer.MIN_VALUE + 10 - 1

ConfigFileApplicationListener
Integer.MIN_VALUE + 10

AnsiOutputApplicationListener
Integer.MIN_VALUE + 10 + 1

LoggingApplicationListener
Integer.MIN_VALUE + 20

ClasspathLoggingApplicationListener
Integer.MIN_VALUE + 20 + 1

DelegatingApplicationListener
0

ParentContextCloserApplicationListener
Integer.MAX_VALUE - 10

FileEncodingApplicationListener
Integer.MAX_VALUE

ClearCachesApplicationListener
Integer.MAX_VALUE

LiquibaseServiceLocatorApplicationListener
Integer.MAX_VALUE

实际执行结果

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

spring boot context 中的监听

对应的监听排序如下

BootstrapApplicationListener
Integer.MIN_VALUE + 5

LoggingSystemShutdownListener
Integer.MIN_VALUE + 5 + 1

RestartListener
0

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

BootstrapApplicationListener
Integer.MIN_VALUE + 5

LoggingSystemShutdownListener
Integer.MIN_VALUE + 5 + 1

CloudFoundryVcapEnvironmentPostProcessor
Integer.MIN_VALUE + 10 - 1

ConfigFileApplicationListener
Integer.MIN_VALUE + 10

AnsiOutputApplicationListener
Integer.MIN_VALUE + 10 + 1

LoggingApplicationListener
Integer.MIN_VALUE + 20

ClasspathLoggingApplicationListener
Integer.MIN_VALUE + 20 + 1

DelegatingApplicationListener
0

RestartListener
0

ParentContextCloserApplicationListener
Integer.MAX_VALUE - 10

FileEncodingApplicationListener
Integer.MAX_VALUE

ClearCachesApplicationListener
Integer.MAX_VALUE

LiquibaseServiceLocatorApplicationListener
Integer.MAX_VALUE

 实际执行结果

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

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

监听执行

监听加载到 SpringApplicationRunListeners 中

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

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

通过 SpringApplication#getRunListeners() 进行加载

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

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

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

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

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

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

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

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

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

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

执行 SpringApplication#prepareEnvironment()

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

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

调用 SimpleApplicationEventMulticaster 的 multicastEvent()

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

调用 SpringApplicationRunListener#environmentPrepared()

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

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

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

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

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

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

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

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

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

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

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

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

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

总结

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

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

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

你可能感兴趣的:(java,spring,spring,boot,spring,cloud,spring,java)