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。