# SpringBoot源码-App启动过程
# 1. 整体流程
- a = new SpringApplication(primarySources)
- a.run
# 1.1 初始化SpringApplication实例
- 判断webApplicationType:通过尝试使用ClassLoader加载对应的标识类来判断WebApp类型,首先判断WEBFLUX,然后根据javax.servlet.Servlet类和WebApplicationContext类判断是否Servlet,都不是则返回None
- 加载所有Jar包中META-INF/spring.facotry文件定义的工厂类:
- 初始化ApplicationContextInitializer类型实例
- 初始化ApplicationListener实例
- 获取MainApplicationClass:通过从调用栈中获取main方法所在的类来获取
# 1.2 启动初始化完成的SpringApplication
- 开启计时器
- 设置java.awt.headless:Headless模式是系统的一种配置模式。在该模式下,系统缺少了显示设备、键盘或鼠标。
- 初始化并启动配置的SpringApplicationRunListeners类型实例:
- SpringBoot包定义一个EventPublishingRunListener实现,此实现在构造过程中会在内部初始化SimpleApplicationEventMulticaster实例:
- 广播ApplicationStartingEvent事件到相应的Listener:
- LoggingApplicationListener:加载log实现,顺序:org.springframework.boot.logging.LoggingSystem定义>logback>log4j>jul
- BackgroundPreinitializer: 提前开始初始化耗时的Bean如Conversion、Jackson等Bean
- DelegatingApplicationListener:无操作
- LiquibaseServiceLocatorApplicationListener:无操作
- Prepare Environment实例:
- 初始化PropertySources:servletConfigInitParams,servletContextInitParams,systemProperties,systemEnvironment
- 初始化ConversionService: 使用ApplicationConversionService实例
- 读取Profile
- Environment Prepare完成,广播ApplicationEnvironmentPreparedEvent事件,调用所有的ApplicationListener,调用对应方法,下面仅挑选重点的几个:
- ConfigFileApplicationListener: 见#### 1.2.1 Config文件加载
- LoggingApplicationListener:处理Logger相关
- Bind过程---->todo
- 自定义Environment转换为标准Environment
- 新增一个ConfigurationPropertySources
- 设置spring.beaninfo.ignore,默认为true,即跳过BeanInfo检测
- 打印Banner
- 创建上下文:ApplicationContext:对于SERVLET模式,实际初始化AnnotationConfigServletWebServerApplicationContext对象,见AnnotationConfigServletWebServerApplicationContext源码解读
- 创建SpringBootExceptionReporter实例
- org.springframework.boot.diagnostics.FailureAnalyzers
- prepare上下文,见AnnotationConfigServletWebServerApplicationContext源码解读
- refresh上下文,见AnnotationConfigServletWebServerApplicationContext源码解读
- afterRefresh,默认无操作
# 1.2.1 Config文件加载
时机:EnvironmentPrepared事件发布后 类:ConfigFileApplicationListener
- 读取EnvironmentPostProcessor列表,并分别调用:
- SystemEnvironmentPropertySourceEnvironmentPostProcessor:将Environment中的SystemEnvironmentPropertySource替换成OriginAwareSystemEnvironmentPropertySource
- SpringApplicationJsonEnvironmentPostProcessor:处理spring.application.json数据为Spring数据源,来源包括环境变量(SPRING_APPLICATION_JSON),系统属性或者properties定义
- CloudFoundryVcapEnvironmentPostProcessor:处理云环境的VCAP数据
- ConfigFileApplicationListener:见1.2.1.1,配置文件加载到Environment
# 1.2.1.1 配置文件加载到Environment
- 时机:EnvironmentPrepared事件广播->调用ApplicationListener->调用ConfigFileApplicationListener的onApplicationEvent方法->加载并调用所有的EnvironmentPostProcessor类型的实例的postProcessEnvironment方法->ConfigFileApplicationListener实例本身属于EnvironmentPostProcessor类,调用其postProcessEnvironment方法
- 方法:ConfigFileApplicationListener实例的postProcessEnvironment方法
- 过程:
- 初始化Loader实例:
- 初始化placeholdersResolver:
new PropertySourcesPlaceholdersResolver(this.environment);
- 初始化resourceLoader:
new DefaultResourceLoader();
- 初始化propertySourceLoaders:
SpringFactoriesLoader.loadFactories(PropertySourceLoader.class, getClass().getClassLoader())
:- org.springframework.boot.env.PropertiesPropertySourceLoader
- org.springframework.boot.env.YamlPropertySourceLoader
- 初始化placeholdersResolver:
- 调用Loader.load()方法
- 获取Active Profile:读取PropertySource(到当前阶段,主要还是SystemProperties和SystemEnvironment值)的spring.profiles.active和spring.profiles.include的配置
- 根据profile读取配置文件:
- 位置:
- 环境变量中spring.config.location配置的位置
- 环境变量中spring.config.additional-location配置的位置
- 预设的位置:注意,由于有reverse操作,所以最后一个为先:classpath:/,classpath:/config/,file:./,file:./config/,
- 加载策略:
- 如果有spring.config.name定义,则加载定义的文件名,否则加载文件名由application开头的文件
- 调用所有的PropertySourceLoader,处理所有其定义的文件后缀对应的文件,对于默认情况,分别有两个默认加载器,其中Properties加载器负责加载
- 位置: