SpringBoot启动过程深度解析——SpringApplicationEvent事件发布
文章使用 spring 相关版本信息:
spring-boot 2.3.4.RELEASE
spring-core 5.2.9.RELEASE
spring-context 5.2.9.RELEASE
spring-web 5.2.9.RELEASE
接下来的文章就以SpringApplication.run的启动方式讲解
@SpringBootApplication
public class Main {
public static void main(String[] args) {
new SpringApplication(Main.class).run();
}
}
springBoot启动过程事件发布的时间线【未完待续…】
ApplicationStartingEvent
ApplicationEnvironmentPreparedEvent
ApplicationContextInitializedEvent
ApplicationPreparedEvent
ApplicationStartedEvent
ApplicationReadyEvent
ApplicationFailedEvent
1. 准备好前期的一些简单设置
2. 【发布】SpringApplication.run() --> ApplicationStartingEvent
3. 生成了环境对象(系统变量,项目环境文件)
4. 【发布】 SpringApplication.run() --> ApplicationEnvironmentPreparedEvent
5. Context上下文已经初始化(执行了ApplicationContextInitializer)
6. 【发布】SpringApplication.run().prepareContext() -> ApplicationContextInitializedEvent
7. Context加载BeanDefinition(自动装配完成)
8. 【发布】SpringApplication.run().prepareContext() -> ApplicationPreparedEvent
9. 执行Spring的refresh的标准化流程
10.【发布】SpringApplication.run() -> ApplicationStartedEvent
10. 遍历执行ApplicationRunner的run方法
12.【发布】SpringApplication.run() -> ApplicationReadyEvent
11. SpringApplication.run()启动异常捕获
14.【发布】SpringApplication.run() -> ApplicationFailedEvent
springBoot启动过程的监听器
事件:ApplicationStartingEvent
监听器:
BackgroundPreinitializer:创建上下文Context一些比较耗时的属性对象(ConversionService、MessageConverter、Jackson、Charset、Validation)
LoggingApplicationListener:根据classloader加载日志模块,哪个加载成功,就使用哪个,执行具体的logging组件的回调方法【只是加载,和执行对调方法】
LiquibaseServiceLocatorApplicationListener:设置Liqui的customResolverServiceLocator(Liquibase:对数据库结构进行管理的插件)
事件:ApplicationEnvironmentPreparedEvent
监听器:
ApplicationPidFileWriter:尝试获取PID,并且保持到指定文件中
FileEncodingApplicationListener:系统文件编码与环境中设置的预期值不匹配,则停止应用程序启动
AnsiOutputApplicationListener:根据spring.output.ansi.enabled参数配置AnsiOutput
ConfigFileApplicationListener:通过从已知文件位置加载属性来配置上下文环境。默认情况下,属性将从以下位置的“application.properties”和/或“application.yml”文件加载
DelegatingApplicationListener:context.listener.classes指定的那些事件监听器注册到多播器中,转发事件给context.listener.classes指定的那些事件监听器
ClasspathLoggingApplicationListener:打印classpath
WebEnvironmentPropertySourceInitializer:重新设置配置源的servletContext
事件:ApplicationContextInitializedEvent
监听器:
DelegatingApplicationListener:转发事件给context.listener.classes指定的那些事件监听器
事件:ApplicationPreparedEvent
监听器:
CloudFoundryVcapEnvironmentPostProcessor:更换自己类中logger的class
ApplicationPidFileWriter:尝试获取PID,并且保持到指定文件中
ConfigFileApplicationListener:向容器添加一个配置源排序的增强器PropertySourceOrderingPostProcessor implements BeanFactoryPostProcessor
ApplicationEnvironmentPreparedEvent:向Context注册Bean:日志系统(loggingSystem、logFile、loggerGroups)
DelegatingApplicationListener:转发事件给context.listener.classes指定的那些事件监听器
事件:ApplicationStartedEvent
监听器:
DelegatingApplicationListener:转发事件给context.listener.classes指定的那些事件监听器
事件:WebServerInitializedEvent
监听器:
SpringApplicationAdminMXBeanRegistrar:设置ready标志=true
事件:ApplicationReadyEvent
监听器:
BackgroundPreinitializer:如果ApplicationStartingEvent事件还没创建完对象,就阻塞主线程
SpringApplicationAdminMXBeanRegistrar:设置ready标志=true
DelegatingApplicationListener:转发事件给context.listener.classes指定的那些事件监听器
ApplicationPidFileWriter:尝试获取PID,并且保持到指定文件中
事件:ApplicationFailedEvent
监听器:
BackgroundPreinitializer:如果ApplicationStartingEvent事件还没创建完对象,就阻塞主线程
DelegatingApplicationListener:转发事件给context.listener.classes指定的那些事件监听器
ClasspathLoggingApplicationListener:打印classpath
LoggingApplicationListener:调用日志系统对应的cleanUp实现方法
springBoot启动过程监听器处理的内容
监听器:BackgroundPreinitializer
事件:ApplicationStartingEvent
创建一些比较耗时的对象
runSafely(new ConversionServiceInitializer());
runSafely(new ValidationInitializer());
runSafely(new MessageConverterInitializer());
runSafely(new JacksonInitializer());
runSafely(new CharsetInitializer());
事件:ApplicationReadyEvent
如果ApplicationStartingEvent事件还没创建完对象,就阻塞主线程
事件:ApplicationFailedEvent
如果ApplicationStartingEvent事件还没创建完对象,就阻塞主线程
监听器:ApplicationPidFileWriter
事件:ApplicationEnvironmentPreparedEvent
尝试获取PID,并且保持到指定文件中
事件:ApplicationPreparedEvent
尝试获取PID,并且保持到指定文件中
事件:ApplicationReadyEvent
尝试获取PID,并且保持到指定文件中
监听器:FileEncodingApplicationListener
事件:ApplicationEnvironmentPreparedEvent
系统文件编码与环境中设置的预期值不匹配,则停止应用程序启动
监听器:ConfigFileApplicationListener
事件:ApplicationEnvironmentPreparedEvent
通过从已知文件位置加载属性来配置上下文环境。默认情况下,属性将从以下位置的“application.properties”和/或“application.yml”文件加载
事件:ApplicationPreparedEvent
向容器添加一个配置源排序的增强器PropertySourceOrderingPostProcessor implements BeanFactoryPostProcessor
监听器:DelegatingApplicationListener
事件:ApplicationEnvironmentPreparedEvent
context.listener.classes指定的那些事件监听器注册到多播器中,转发事件给context.listener.classes指定的那些事件监听器
其他事件:
转发事件给context.listener.classes指定的那些事件监听器
监听器:ClasspathLoggingApplicationListener
事件:ApplicationEnvironmentPreparedEvent
打印classpath
事件:ApplicationFailedEvent
打印classpath
监听器:LoggingApplicationListener
事件:ApplicationStartingEvent
根据classloader加载日志模块,哪个加载成功,就使用哪个,执行具体的logging组件的回调方法【只是加载,和执行对调方法】
事件:ApplicationEnvironmentPreparedEvent
根据配置创建对应的日志系统
事件:ApplicationPreparedEvent
向Context注册Bean:日志系统(loggingSystem、logFile、loggerGroups)
事件:ContextClosedEvent && 没有父容器
调用日志系统对应的cleanUp实现方法
事件:ApplicationFailedEvent
调用日志系统对应的cleanUp实现方法