SpringBoot启动配置原理
1 启动流程
- 1️⃣创建SpringApplication对象。
public class SpringApplication {
//SpringBoot应用启动,调用此方法
public static ConfigurableApplicationContext run(Object source, String... args) {
return run(new Object[] { source }, args);
}
public static ConfigurableApplicationContext run(Object[] sources, String[] args) {
return new SpringApplication(sources).run(args);
}
public SpringApplication(Object... sources) {
//初始化
initialize(sources);
}
private void initialize(Object[] sources) {
//保存主配置类
if (sources != null && sources.length > 0) {
this.sources.addAll(Arrays.asList(sources));
}
//当前应用是否是web应用
this.webEnvironment = deduceWebEnvironment();
//从类路径下找到META-INF/spring.factories配置的所有ApplicationContextInitializer,然后保存起来
setInitializers((Collection) getSpringFactoriesInstances(
ApplicationContextInitializer.class));
//从类路径下找到META-INF/spring.factories配置的所有ApplicationListener,然后保存起来
setListeners((Collection) getSpringFactoriesInstances(ApplicationListener.class));
//从多个配置类中找到有main方法的主配置类
this.mainApplicationClass = deduceMainApplicationClass();
}
//其他略
}
- 2️⃣通过SpringApplication对象调用run()方法。
public class SpringApplication {
/**
* Run the Spring application, creating and refreshing a new
* {@link ApplicationContext}.
* @param args the application arguments (usually passed from a Java main method)
* @return a running {@link ApplicationContext}
*/
public ConfigurableApplicationContext run(String... args) {
StopWatch stopWatch = new StopWatch();
stopWatch.start();
ConfigurableApplicationContext context = null;
FailureAnalyzers analyzers = null;
configureHeadlessProperty();
//获取SpringApplicationRunListeners,从类路径下的找到META-INF/spring.factories配置的所有SpringApplicationRunListener
SpringApplicationRunListeners listeners = getRunListeners(args);
//回调所有SpringApplicationRunListener的starting方法
listeners.starting();
try {
//封装命令行参数
ApplicationArguments applicationArguments = new DefaultApplicationArguments(
args);
/*
* 准备环境:
* - 创建环境完成后回调所有SpringApplicationRunListener的environmentPrepared方法;表示环境准备完成
*/
ConfigurableEnvironment environment = prepareEnvironment(listeners,
applicationArguments);
//打印Banner
Banner printedBanner = printBanner(environment);
//创建ApplicationContext。决定创建Web的IOC容器还是普通的IOC容器
context = createApplicationContext();
analyzers = new FailureAnalyzers(context);
//准备上下文环境,将environment保存到IOC容器中,applyInitializers(context);回到之前保存的所有的ApplicationContextInitializer的initialize()方法,回调listeners.contextPrepared(context);
prepareContext(context, environment, listeners, applicationArguments,
printedBanner);
//prepareContext完成后,回调listeners.contextLoaded(context);
//刷新容器。IOC容器初始化
refreshContext(context);
//从IOC容器中获取所有的ApplicationRunner和CommandLineRunner进行回调
afterRefresh(context, applicationArguments);
//所有的SpringApplicationRunListener回调finished方法
listeners.finished(context, null);
stopWatch.stop();
if (this.logStartupInfo) {
new StartupInfoLogger(this.mainApplicationClass)
.logStarted(getApplicationLog(), stopWatch);
}
//整个SpringBoot启动完成以后,返回启动的IOC容器
return context;
}
catch (Throwable ex) {
handleRunFailure(context, listeners, analyzers, ex);
throw new IllegalStateException(ex);
}
}
}
2 总结事件回调机制
-
需要配置在META-INF/spring.factories的事件是:
- ApplicationContextInitializer。
- ApplicationListener。
-
不需要配置在META-INF/spring.factories,只需要加入到IOC容器的事件是:
- ApplicationRunner。
- CommandLineRunner。