##springboot启动代码分析
1. 创建SpringApplication对象
1-1 创建SpringApplication时,会调用initialize方法,这个方法会做4件事情。
- 赋值springApplication的webEnvironment属性。 用来判断是否web环境。
- 赋值springApplication的initializers属性。 加载spring.factories文件中定义的ApplicationContextInitializer实现类。ApplicationContextInitializer这个接口会在ConfiurableApplicationContext#refresh() 前被调用,允许我们对ConfiurableApplicationContext做一些设置和处理。
- 赋值springApplication的initializers属性。 加载spring.factories文件中定义的ApplicationListener实现类。 ApplicationListener接口的实现类会和applicationContext进行绑定,在接收到applicationContext发出的通知事件后进行一些处理。是观察者模式的一种实现。
- 赋值springApplication的mainApplicationClass属性。这个属性表示springApplication的main方法的类。
private void initialize(Object[] sources) {
if (sources != null && sources.length > 0) {
this.sources.addAll(Arrays.asList(sources));
}
this.webEnvironment = deduceWebEnvironment();
setInitializers((Collection) getSpringFactoriesInstances(
ApplicationContextInitializer.class));
setListeners((Collection) getSpringFactoriesInstances(ApplicationListener.class));
this.mainApplicationClass = deduceMainApplicationClass();
}
2.运行springApplication.run()方法
2-1 加载spring.factories文件中定义的SpringApplicationRunListener实现类,并启动。 通过实现SpringApplicationRunListener接口回调可以让用户在springApplication启动的各个流程中加入自己的逻辑。包括:
- 开始启动
- Environment构建完成
- ApplicationContext构建完成
- ApplicationContext完成加载
- ApplicationContext完成刷新并启动
package org.springframework.boot;
public interface SpringApplicationRunListener {
// 在run()方法开始执行时,该方法就立即被调用,可用于在初始化最早期时做一些工作
void starting();
// 当environment构建完成,ApplicationContext创建之前,该方法被调用
void environmentPrepared(ConfigurableEnvironment environment);
// 当ApplicationContext构建完成时,该方法被调用
void contextPrepared(ConfigurableApplicationContext context);
// 在ApplicationContext完成加载,但没有被刷新前,该方法被调用
void contextLoaded(ConfigurableApplicationContext context);
// 在ApplicationContext刷新并启动后,CommandLineRunners和ApplicationRunner未被调用前,该方法被调用
void started(ConfigurableApplicationContext context);
// 在run()方法执行完成前该方法被调用
void running(ConfigurableApplicationContext context);
// 当应用运行出错时该方法被调用
void failed(ConfigurableApplicationContext context, Throwable exception);
}