1. 获取、启动运行过程中的监听器
run方法 SpringApplicationRunListeners listeners = this.getRunListeners(args);
getRunListeners() 方法 然后调用
getSpringFactoriesInstances()方法
然后loadFactoryNamesd读取spring.factory里面的事例
最后注册 EventPublishingRunListener
EventPublishingRunListener的方法用来触发 SpringApplicationEvent中的不同子类
总结: 这一步其实就是广播了ApplicationStartingEvent事件来触发监听这个事件的ApplicationListener
2:环境构建
ConfigurableEnvironment environment = this.prepareEnvironment(listeners, applicationArguments);
环境构建这一步加载了 系统环境配置、用户自定义配置 并且广播了ApplicationEnvironmentPreparedEvent事件,触发监听器
3. 创建IOC容器
context = createApplicationContext();
根据webApplicationType 决定创建的类型
这里是servlet 所以是 AnnotationConfigServletWebServerApplicationContext
switch(this.webApplicationType) {
case SERVLET:
contextClass = Class.forName("org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext");
break;
case REACTIVE:
contextClass = Class.forName("org.springframework.boot.web.reactive.context.AnnotationConfigReactiveWebServerApplicationContext");
break;
default:
contextClass = Class.forName("org.springframework.context.annotation.AnnotationConfigApplicationContext");
}
4. IOC容器的前置处理
this.prepareContext(context, environment, listeners, applicationArguments, printedBanner);
a、设置环境参数
b、执行后置处理
c、执行初始化器
d、设置banner
e、广播容器准备完成事件,触发监听器
f、获取启动累制定的参数 可有多个
g、加载启动类 将启动类注入容器 加入到 beanDefinitionMap
h、发布容器已加载事件
在刷新容器之前做准备,其中有一个非常关键的操作:将启动类注入容器,为后续的自动化配置奠定基础
5. 刷新容器
初始化资源,初始化上下文广播器
6. IOC容器的后置处理
afterRefresh(context, applicationArguments);
默认为空,如果有自定义需求可以重写,比如打印一些启动结束日志等。
7. 发出结束执行的事件
同样是EventPublishingRunListener这个监听器,广播ApplicationStartedEvent事件
但是这里广播事件和前几次不同,并不是广播给SpringApplication中的监听器(在构建过程中从spring.factories文件获取的监听器)
。因此在IOC容器中注入的监听器(使用@Component等方式注入的)也能够生效。前面几个事件只有在spring.factories文件中设置的监听器才会生效
8.执行runners
callRunners(context, applicationArguments);
有两种
ApplicationRunner
CommandLineRunner
springApplication方法
获取、启动运行过程中的监听器 ----> 环境构建 ----> ️创建IOC容器
|
|
|
IOC容器后置处理 <---- 创建IOC容器 <---- IOC容器前置处理
|
|
|
发出结束执行的事件 ---- > ️执行runners
public ConfigurableApplicationContext run(String... args) {
StopWatch stopWatch = new StopWatch();
stopWatch.start();
ConfigurableApplicationContext context = null;
Collection<SpringBootExceptionReporter> exceptionReporters = new ArrayList();
this.configureHeadlessProperty();
1⃣️获取、启动运行过程监听器
SpringApplicationRunListeners listeners = this.getRunListeners(args);
listeners.starting();
Collection exceptionReporters;
try {
ApplicationArguments applicationArguments = new DefaultApplicationArguments(args);
2⃣️环境构建
ConfigurableEnvironment environment = this.prepareEnvironment(listeners, applicationArguments);
this.configureIgnoreBeanInfo(environment);
Banner printedBanner = this.printBanner(environment);
3⃣️创建IOC容器
context = this.createApplicationContext();
exceptionReporters = this.getSpringFactoriesInstances(SpringBootExceptionReporter.class, new Class[]{ConfigurableApplicationContext.class}, context);
4⃣️IOC容器前置处理
this.prepareContext(context, environment, listeners, applicationArguments, printedBanner);
5⃣️刷新容器
this.refreshContext(context);
6⃣️IOC容器后置处理
this.afterRefresh(context, applicationArguments);
stopWatch.stop();
if (this.logStartupInfo) {
(new StartupInfoLogger(this.mainApplicationClass)).logStarted(this.getApplicationLog(), stopWatch);
}
7⃣️发出结束执行的事件
listeners.started(context);
8⃣️执行runners
this.callRunners(context, applicationArguments);
} catch (Throwable var10) {
this.handleRunFailure(context, var10, exceptionReporters, listeners);
throw new IllegalStateException(var10);
}
try {
listeners.running(context);
return context;
} catch (Throwable var9) {
this.handleRunFailure(context, var9, exceptionReporters, (SpringApplicationRunListeners)null);
throw new IllegalStateException(var9);
}
}