欢迎各位关注我的笔记仓库,clone 仓库到本地后使用 Typora 阅读效果更好。
如果大家只关注 SpringBoot 如何自动装配,可以只看“注解分析”和“装配流程”两个小节
启动流程
应用启动:
@SpringBootApplication
public class BootApplication {
public static void main(String[] args) {
// 启动代码
SpringApplication.run(BootApplication.class, args);
}
}
SpringApplication 构造方法:
-
this.resourceLoader = resourceLoader
:资源加载器,初始为 null -
this.webApplicationType = WebApplicationType.deduceFromClasspath()
:判断当前应用的类型,是响应式还是 Web 类 -
this.bootstrapRegistryInitializers = getBootstrapRegistryInitializersFromSpringFactories()
:获取引导器- 去
META-INF/spring.factories
文件中找 org.springframework.boot.Bootstrapper - 寻找的顺序:classpath → spring-beans → boot-devtools → springboot → boot-autoconfigure
- 去
-
setInitializers(getSpringFactoriesInstances(ApplicationContextInitializer.class))
:获取初始化器- 去
META-INF/spring.factories
文件中找 org.springframework.context.ApplicationContextInitializer
- 去
-
setListeners((Collection) getSpringFactoriesInstances(ApplicationListener.class))
:获取监听器- 去
META-INF/spring.factories
文件中找 org.springframework.context.ApplicationListener
- 去
-
this.mainApplicationClass = deduceMainApplicationClass()
:获取出 main 程序类
SpringApplication#run(String... args):
-
StopWatch stopWatch = new StopWatch()
:停止监听器,监控整个应用的启停 -
stopWatch.start()
:记录应用的启动时间 -
bootstrapContext = createBootstrapContext()
:创建引导上下文环境bootstrapContext = new DefaultBootstrapContext()
:创建默认的引导类环境this.bootstrapRegistryInitializers.forEach()
:遍历所有的引导器调用 initialize 方法完成初始化设置
-
configureHeadlessProperty()
:让当前应用进入 headless 模式 -
listeners = getRunListeners(args)
:获取所有 RunListener(运行监听器)- 去
META-INF/spring.factories
文件中找 org.springframework.boot.SpringApplicationRunListener
- 去
-
listeners.starting(bootstrapContext, this.mainApplicationClass)
:遍历所有的运行监听器调用 starting 方法 -
applicationArguments = new DefaultApplicationArguments(args)
:获取所有的命令行参数 -
environment = prepareEnvironment(listeners, bootstrapContext, applicationArguments)
:准备环境-
environment = getOrCreateEnvironment()
:返回或创建基础环境信息对象switch (this.webApplicationType)
:根据当前应用的类型创建环境case SERVLET
:Web 应用环境对应 ApplicationServletEnvironmentcase REACTIVE
:响应式编程对应 ApplicationReactiveWebEnvironmentdefault
:默认为 Spring 环境 ApplicationEnvironment
-
configureEnvironment(environment, applicationArguments.getSourceArgs())
:读取所有配置源的属性值配置环境 -
ConfigurationPropertySources.attach(environment)
:属性值绑定环境信息sources.addFirst(ATTACHED_PROPERTY_SOURCE_NAME,..)
:把 configurationProperties 放入环境的属性信息头部
-
listeners.environmentPrepared(bootstrapContext, environment)
:运行监听器调用 environmentPrepared(),EventPublishingRunListener 发布事件通知所有的监听器当前环境准备完成 -
DefaultPropertiesPropertySource.moveToEnd(environment)
:移动 defaultProperties 属性源到环境中的最后一个源 -
bindToSpringApplication(environment)
:与容器绑定当前环境 -
ConfigurationPropertySource
-