SpringBoot启动流程
public static ConfigurableApplicationContext run(Class<?>[] primarySources, String[] args) {
return new SpringApplication(primarySources).run(args);
}
1. 创建SpringApplication
public SpringApplication(ResourceLoader resourceLoader, Class<?>... primarySources) {
// 资源加载类
this.resourceLoader = resourceLoader;
Assert.notNull(primarySources, "PrimarySources must not be null");
this.primarySources = new LinkedHashSet<>(Arrays.asList(primarySources));
this.webApplicationType = WebApplicationType.deduceFromClasspath();
// 设置初始化类
setInitializers((Collection) getSpringFactoriesInstances(ApplicationContextInitializer.class));
// 设置Listener监听
setListeners((Collection) getSpringFactoriesInstances(ApplicationListener.class));
// 查找主main函数入口类
this.mainApplicationClass = deduceMainApplicationClass();
}
设置初始化类
从 META-INF/spring.factories 配置文件中,加载初始化类
# Application Context Initializers
org.springframework.context.ApplicationContextInitializer=\
org.springframework.boot.context.ConfigurationWarningsApplicationContextInitializer,\
org.springframework.boot.context.ContextIdApplicationContextInitializer,\
org.springframework.boot.context.config.DelegatingApplicationContextInitializer,\
org.springframework.boot.rsocket.context.RSocketPortInfoApplicationContextInitializer,\
org.springframework.boot.web.context.ServerPortInfoApplicationContextInitializer
设置Listener监听
从 META-INF/spring.factories 配置文件中,加载Listener类
# Application Listeners
org.springframework.context.ApplicationListener=\
org.springframework.boot.ClearCachesApplicationListener,\
org.springframework.boot.builder.ParentContextCloserApplicationListener,\
org.springframework.boot.cloud.CloudFoundryVcapEnvironmentPostProcessor,\
org.springframework.boot.context.FileEncodingApplicationListener,\
org.springframework.boot.context.config.AnsiOutputApplicationListener,\
org.springframework.boot.context.config.ConfigFileApplicationListener,\
org.springframework.boot.context.config.DelegatingApplicationListener,\
org.springframework.boot.context.logging.ClasspathLoggingApplicationListener,\
org.springframework.boot.context.logging.LoggingApplicationListener,\
org.springframework.boot.liquibase.LiquibaseServiceLocatorApplicationListener
2. 运行SpringApplicaiton
2.1 获取SpringApplicationRunListener,触发 starting
SpringApplicationRunListeners listeners = getRunListeners(args);
listeners.starting();
2.2 准备环境配置
ConfigurableEnvironment environment = prepareEnvironment(listeners, applicationArguments);
2.3 打印Banner
Banner printedBanner = printBanner(environment);
2.4 创建容器 createApplicationContext
校验web类型,构建容器
- 如果是 web 容器,创建
AnnotationConfigServletWebServerApplicationContext
- 如果是 Reactive 响应式 web 容器,创建
AnnotationConfigReactiveWebServerApplicationContext
- 非web 容器,创建
AnnotationConfigApplicationContext
2.5 准备容器 prepareContext
-
执行 postProcessApplicationContext 前置准备
-
遍历 ApplicationContextInitializer,执行 initialize 初始化
-
遍历 Listener 执行 contextPrepared 方法
listeners.contextPrepared(context);
-
执行 load 加载资源
load(context, sources.toArray(new Object[0]))
-
遍历 Listener 执行 contentLoaded 方法
listeners.contextLoaded(context);
2.6 刷新容器 refreshContext
- 执行 Spring 容器 refresh 刷新容器,注册Bean
2.7 容器启动完成后工作
-
afterRefresh 容器刷新后执行
-
遍历 Listener 执行 started 方法
listeners.started(context)
-
执行一次性任务
- 遍历 ApplicationRunner 执行
- 遍历 CommandLineRunner 执行
-
遍历 Listener 执行 running 方法
listeners.running(context)
2.8 异常处理
- 发布异常事件
context.publishEvent(new ExitCodeEvent(context, exitCode))
- 遍历 Listener 执行 failed 方法
listeners.failed(context)
- 遍历 SpringBootExceptionReporter ,上报异常