SpringBoot ApplicationEvent详解

ApplicationStartingEvent 阶段

LoggingApplicationListener#onApplicationStartingEvent

初始化日志工厂,LoggingSystemFactory接口,可以通过spring.factories进行定制

可以通过System.setProperty("org.springframework.boot.logging.LoggingSystem","类全路径限定名或者none") 指定log实现类

如果配置的是none,则返回 org.springframework.boot.logging.LoggingSystem.NoOpLoggingSystem

springboot默认指定了三种类型:

org.springframework.boot.logging.logback.LogbackLoggingSystem.Factory

org.springframework.boot.logging.log4j2.Log4J2LoggingSystem.Factory

org.springframework.boot.logging.java.JavaLoggingSystem.Factory


BackgroundPreinitializer#onApplicationEvent 在当前阶段不做任何处理!!!

可以通过System.setProperty("spring.backgroundpreinitializer.ignore","true|false")

同时满足服务器是多核cpu并且非GraalVM环境

来指定是否通过后台线程去加载某些资源,默认是单独开一个线程来加载某些资源

线程名称:background-preinit

后台加载的资源:

ConversionServiceInitializer.class

ValidationInitializer.class

MessageConverterInitializer.class

JacksonInitializer.class

CharsetInitializer.class

有异常直接忽略


DelegatingApplicationListener#onApplicationEvent 在当前阶段不做任何处理!!!

可以通过配置 context.listener.classes 属性来指定要执行的listener,是一个复合包装类

内部定义了SimpleApplicationEventMulticaster事件驱动类,用来指定配置的listener

==========

ApplicationEnvironmentPreparedEvent 阶段

EnvironmentPostProcessorApplicationListener#onApplicationEvent

onApplicationEnvironmentPreparedEvent((ApplicationEnvironmentPreparedEvent) event);

获取ConfigurableEnvironment实例

获取SpringApplication实例

通过SpringApplication实例.getResourceLoader()和ConfigurableEnvironment实例.getBootstrapContext() 获取 EnvironmentPostProcessors

所有实现了 org.springframework.boot.env.EnvironmentPostProcessor 接口的实现类,同样可以通过 spring.factories进行定制

开始遍历

1、RandomValuePropertySourceEnvironmentPostProcessor#postProcessEnvironment

将RandomValuePropertySource添加到systemEnvironment这个属性解析器集合的最后一位

RandomValuePropertySource: 用法,配置属性以random开头

比如:random.int 返回正负32位以内的一个伪随机数字

random.long 返回正负64位以内的一个伪随机数字

random.int(0,9) 包含0不包含9 中的一个伪随机数字

random.long[0,9] 包含0不包含9 中的一个伪随机数字

() 和 [] 或者 $$ 作用都一样 前后任意两个字符括起来,数字使用逗号分隔即可

2、SystemEnvironmentPropertySourceEnvironmentPostProcessor#postProcessEnvironment

判断是否设置了 SpringApplication.environmentPrefix 属性,如果设置了将systemEnvironment(SystemEnvironmentPropertySource)

的数据封装为OriginAwareSystemEnvironmentPropertySource类(SystemEnvironmentPropertySource的子类),有prefix属性.

spring.main.environment-prefix:不允许这样设置

可以通过 SpringApplicationBuilder.environmentPrefix("xx") 来设置,可以以 . - _ 等结尾,

3、SpringApplicationJsonEnvironmentPostProcessor#postProcessEnvironment

解析json属性,使用spring.application.json或者SPRING_APPLICATION_JSON命令行参数指定,按序返回有效的第一个进行解析.

解析成功后,将json属性封装为JsonPropertySource,放到servlet sources前面,如果不是servlet环境,则放在第一位

解析json属性的解析器:

org.springframework.boot.json.JsonParserFactory#getJsonParser: 指定了4种json解析器

com.fasterxml.jackson.databind.ObjectMapper

com.google.gson.Gson

org.yaml.snakeyaml.Yaml

org.springframework.boot.json.BasicJsonParser

按以上顺序进行加载,加载成功就返回对应的对象实例

4、CloudFoundryVcapEnvironmentPostProcessor#postProcessEnvironment 在springcloud环境下生效

判断是否设置了 spring.main.cloud-platform VCAP_APPLICATION VCAP_SERVICES 满足任意一个

设置了 添加 vcap sources

5、ConfigDataEnvironmentPostProcessor#postProcessEnvironment **你个** 加载并且解析设定的配置文件

spring.config.on-not-found: 配置找不到的处理方法,参考ConfigDataNotFoundAction枚举类

SpringApplication.additionalProfiles 通过 builder 构建

加载指定的配置文件并且设置environment中的profiles

ConfigData Location Resolvers

org.springframework.boot.context.config.ConfigDataLocationResolver=\

org.springframework.boot.context.config.ConfigTreeConfigDataLocationResolver,\

org.springframework.boot.context.config.StandardConfigDataLocationResolver

ConfigData Loaders

org.springframework.boot.context.config.ConfigDataLoader=\

org.springframework.boot.context.config.ConfigTreeConfigDataLoader,\

org.springframework.boot.context.config.StandardConfigDataLoader

6、DebugAgentEnvironmentPostProcessor#postProcessEnvironment

reactor.tools.agent.ReactorDebugAgent有这个类并且spring.reactor.debug-agent.enabled属性配置为true时

执行 ReactorDebugAgent init() 方法

7、IntegrationPropertiesEnvironmentPostProcessor#postProcessEnvironment

META-INF/spring.integration.properties 这个文件存在时加载内容并且转化为IntegrationPropertiesPropertySource添加到sources结尾


AnsiOutputApplicationListener#onApplicationEvent

进行属性绑定 spring.output.ansi.enabled org.springframework.boot.ansi.AnsiOutput#enabled 参考 Enabled 枚举类

spring.output.ansi.console-available AnsiOutput.consoleAvailable = consoleAvailable


LoggingApplicationListener#onApplicationEvent

日志文件和属性初始化配置


BackgroundPreinitializer#onApplicationEvent

可以通过System.setProperty("spring.backgroundpreinitializer.ignore","true|false")

同时满足服务器是多核cpu并且非GraalVM环境

来指定是否通过后台线程去加载某些资源,默认是单独开一个线程来加载某些资源

线程名称:background-preinit

后台加载的资源:

ConversionServiceInitializer.class

ValidationInitializer.class

MessageConverterInitializer.class

JacksonInitializer.class

CharsetInitializer.class

有异常直接忽略


DelegatingApplicationListener#onApplicationEvent

可以通过配置 context.listener.classes 属性来指定要执行的listener,是一个复合包装类

内部定义了SimpleApplicationEventMulticaster事件驱动类,用来指定配置的listener


FileEncodingApplicationListener#onApplicationEvent1

spring.mandatory-file-encoding: 查看是否配置了此属性,强制编码,如果这个与file.encoding不符合报错!!!

==========

bindToSpringApplication(environment) // 将spring.main开头的属性配置绑定到SpringApplication属性上

==========

applyInitializers(context); // 执行ApplicationContextInitializer接口的实现类

==========

ApplicationContextInitializedEvent

BackgroundPreinitializer#onApplicationEvent 此阶段啥也不做!!!


DelegatingApplicationListener#onApplicationEvent 此阶段啥也不做!!!

==========

ApplicationPreparedEvent

EnvironmentPostProcessorApplicationListener#onApplicationEvent

onApplicationPreparedEvent() > EnvironmentPostProcessorApplicationListener#finish() > DeferredLogs#switchOverAll()

打印日志


LoggingApplicationListener#onApplicationEvent

注册springBootLoggingSystem单例Bean

logFile存在并且springBootLogFile不存在这个Bean时注册springBootLogFile单例Bean

loggerGroups存在并且springBootLoggerGroups不存在这个Bean时注册springBootLoggerGroups单例Bean

springBootLoggingLifecycle单例Bean不存在BeanFactory.getParent为空时注册springBootLoggingLifecycle单例Bean


BackgroundPreinitializer#onApplicationEvent 此阶段啥也不做!!!


DelegatingApplicationListener#onApplicationEvent 此阶段啥也不做!!!

==========

中间存在的各种事件驱动类

ServletWebServerInitializedEvent

SpringApplicationAdminMXBeanRegistrar#onApplicationEvent : onWebServerInitializedEvent((WebServerInitializedEvent) event);

DelegatingApplicationListener#onApplicationEvent 此阶段啥也不做!!!

ServerPortInfoApplicationContextInitializer#onApplicationEvent : 绑定server.ports sources


ContextRefreshedEvent

DelegatingApplicationListener#onApplicationEvent 此阶段啥也不做!!!

ConditionEvaluationReportLoggingListener.ConditionEvaluationReportListener#onApplicationEvent 打印方法 ConditionEvaluationReportMessage

ClearCachesApplicationListener#onApplicationEvent 清理加载反射field和method的缓存数据,调用类加载器的clearCache方法清理缓存

SharedMetadataReaderFactoryContextInitializer.SharedMetadataReaderFactoryBean#onApplicationEvent 清理加载的class缓存数据

ResourceUrlProvider#onApplicationEvent 静态资源 /webjars/** 和 /static/**

==========

ApplicationStartedEvent

BackgroundPreinitializer#onApplicationEvent 此阶段啥也不做!!!


DelegatingApplicationListener#onApplicationEvent 此阶段啥也不做!!!


StartupTimeMetricsListener#onApplicationEvent

设置埋点监控 TimeGauge


TomcatMetricsBinder#onApplicationEvent

设置tomcat监控绑定


AvailabilityChangeEvent

DelegatingApplicationListener#onApplicationEvent 此阶段啥也不做!!!


ApplicationAvailabilityBean#onApplicationEvent 添加到 org.springframework.boot.availability.ApplicationAvailabilityBean#events 集合中 应用启动好了

==========

ApplicationReadyEvent

SpringApplicationAdminMXBeanRegistrar#onApplicationEvent 应用准备好了


BackgroundPreinitializer#onApplicationEvent 此阶段啥也不做!!!


StartupTimeMetricsListener#onApplicationEvent 注册TimeGauge埋点监控


DelegatingApplicationListener#onApplicationEvent 此阶段啥也不做!!!

==========

AvailabilityChangeEvent

ApplicationAvailabilityBean#onApplicationEvent 添加到 org.springframework.boot.availability.ApplicationAvailabilityBean#events 集合中 应用准备好了

相关推荐
万物得其道者成几秒前
React Zustand状态管理库的使用
开发语言·javascript·ecmascript
学步_技术6 分钟前
Python编码系列—Python抽象工厂模式:构建复杂对象家族的蓝图
开发语言·python·抽象工厂模式
【D'accumulation】20 分钟前
典型的MVC设计模式:使用JSP和JavaBean相结合的方式来动态生成网页内容典型的MVC设计模式
java·设计模式·mvc
wn53130 分钟前
【Go - 类型断言】
服务器·开发语言·后端·golang
试行34 分钟前
Android实现自定义下拉列表绑定数据
android·java
茜茜西西CeCe40 分钟前
移动技术开发:简单计算器界面
java·gitee·安卓·android-studio·移动技术开发·原生安卓开发
Hello-Mr.Wang42 分钟前
vue3中开发引导页的方法
开发语言·前端·javascript
救救孩子把1 小时前
Java基础之IO流
java·开发语言
WG_171 小时前
C++多态
开发语言·c++·面试
小菜yh1 小时前
关于Redis
java·数据库·spring boot·redis·spring·缓存