springBoot启动流程
流程的详情
现在文字介绍下一个普通的springboot启动加载流程
首先构造SpringApplication
- 最开始是加载资源加载器。(当然实际上是个空)
this(null, primarySources);
public SpringApplication(ResourceLoader resourceLoader, Class<?>... primarySources) {
// 资源加载器
this.resourceLoader = resourceLoader;
// ...
}
- 设置主类
this.primarySources = new LinkedHashSet<>(Arrays.asList(primarySources));
- 设置web应用类型
this.webApplicationType = WebApplicationType.deduceFromClasspath()
- 获得所有的应用初始化对象
- 获得所有的监听器
- 返回调用main方法的主类
this.mainApplicationClass = deduceMainApplicationClass
执行run方法
- 启动监听器
listeners.starting()
- 创建配置,并通过监听器实现配置的修改
prepareEnvironment(listeners,applicationArguments)
这一阶段 FileEncodingApplicationListener、AnsiOutputApplicationListener、ConfigFileApplicationListener、DelegatingApplicationListener、ClasspathLoggingApplicationListener、LoggingApplicationListener都会参与监听,这里也是配置加载的核心逻辑,可以详细看看
-
创建应用
createApplicationContext()
-
为应用添加额外内容
prepareContext
- context.setEnvironment(environment) 这次才是真正将环境设置到应用中,一开始我都以为
bindToSpringApplication
这个方法也是设置环境到应用中,但是读了几遍后发现事情没有那么简单………… - 设置类名称生成器
createApplicationContext
,虽然下面还有一些逻辑设置资源加载等内容,但是我各种调试都无法进入下面的逻辑内容,不知道需要如何配置 - 初始化应用
applyInitializers
主要是调用ApplicationContextInitializer的实现类
在这里面,执行的ApplicationContextInitializer执行了对配置的校验,应用ID的生成,内置Web 服务器 (Tomcat)端口的配置
- 发布了事件
contextPrepared
然而没有任何实现 - 加载了主类
- 发布了ApplicationPreparedEvent 事件
这一阶段 ConfigFileApplicationListener、LoggingApplicationListener都会参与监听,这里主要添加了一些处理逻辑到beanFactory,可以详细看看
- context.setEnvironment(environment) 这次才是真正将环境设置到应用中,一开始我都以为
-
启动监听器
refreshContext(context)
这一阶段,是spring的核心。实现了应用的各种bean的加载,各种监听器、处理器的业务逻辑。但是这一段逻辑不是springboot的而是spring提供的。对spring启动和刷新不熟悉的可以去了解下。spring中非常重要和核心的逻辑
其实到这一步项目已经启动了
- 刷新应用的后置处理
afterRefresh
空方法 - 发布事件
listeners.started(context)
这一阶段 LoggingApplicationListener参与监听,主要是日志打印
- 发布事件
listeners.running(context)
这一阶段 LoggingApplicationListener参与监听,主要是日志打印
总结
其实现在通篇看下来,springboot源码最主要的内容就是配置的加载。但是项目启动却是应用的刷新启动。所以在看springboot内容前,一定要了解过spring 应用(容器、上下文、applicationContext)的相关内容!!!