四、核心方法run()
//4
public ConfigurableApplicationContext run(String... args) {
//開啟任務(wù)執(zhí)行時間監(jiān)聽器
StopWatch stopWatch = new StopWatch();
stopWatch.start();
ConfigurableApplicationContext context = null;
Object analyzers = null;
//設(shè)置系統(tǒng)屬性『java.awt.headless』邓梅,為true則啟用headless模式支持
this.configureHeadlessProperty();
//通過*SpringFactoriesLoader*檢索*META-INF/spring.factories*,
//找到聲明的所有SpringApplicationRunListener的實現(xiàn)類并將其實例化替饿,
//之后逐個調(diào)用其started()方法赞别,廣播SpringBoot要開始執(zhí)行了。
SpringApplicationRunListeners listeners = this.getRunListeners(args);
listeners.started();
try {
DefaultApplicationArguments ex = new DefaultApplicationArguments(args);
//創(chuàng)建并配置當前SpringBoot應用將要使用的Environment(包括配置要使用的PropertySource以及Profile),
//并遍歷調(diào)用所有的SpringApplicationRunListener的environmentPrepared()方法岛琼,廣播Environment準備完畢底循。
ConfigurableEnvironment environment = this.prepareEnvironment(listeners, ex);
//決定是否打印Banner
Banner printedBanner = this.printBanner(environment);
//根據(jù)webEnvironment的值來決定創(chuàng)建何種類型的ApplicationContext對象
//如果是web環(huán)境,則創(chuàng)建org.springframework.boot.context.embedded.AnnotationConfigEmbeddedWebApplicationContext
//否則創(chuàng)建org.springframework.context.annotation.AnnotationConfigApplicationContext
context = this.createApplicationContext();
//注冊異常分析器
new FailureAnalyzers(context);
//為ApplicationContext加載environment衷恭,之后逐個執(zhí)行ApplicationContextInitializer的initialize()方法來進一步封裝ApplicationContext此叠,
//并調(diào)用所有的SpringApplicationRunListener的contextPrepared()方法,【EventPublishingRunListener只提供了一個空的contextPrepared()方法】随珠,
//之后初始化IoC容器灭袁,并調(diào)用SpringApplicationRunListener的contextLoaded()方法,廣播ApplicationContext的IoC加載完成窗看,
//這里就包括通過**@EnableAutoConfiguration**導入的各種自動配置類茸歧。
this.prepareContext(context, environment, listeners, ex, printedBanner);
//初始化所有自動配置類,調(diào)用ApplicationContext的refresh()方法
this.refreshContext(context);
//遍歷所有注冊的ApplicationRunner和CommandLineRunner显沈,并執(zhí)行其run()方法软瞎。
//該過程可以理解為是SpringBoot完成ApplicationContext初始化前的最后一步工作逢唤,
//我們可以實現(xiàn)自己的ApplicationRunner或者CommandLineRunner,來對SpringBoot的啟動過程進行擴展涤浇。
this.afterRefresh(context, ex);
//調(diào)用所有的SpringApplicationRunListener的finished()方法鳖藕,廣播SpringBoot已經(jīng)完成了ApplicationContext初始化的全部過程。
listeners.finished(context, (Throwable)null);
//關(guān)閉任務(wù)執(zhí)行時間監(jiān)聽器
stopWatch.stop();
//如果開啟日志只锭,則答應執(zhí)行是時間
if(this.logStartupInfo) {
(new StartupInfoLogger(this.mainApplicationClass)).logStarted(this.getApplicationLog(), stopWatch);
}
return context;
} catch (Throwable var9) {
//調(diào)用異常分析器打印報告著恩,調(diào)用所有的SpringApplicationRunListener的finished()方法將異常信息發(fā)布出去
this.handleRunFailure(context, listeners, (FailureAnalyzers)analyzers, var9);
throw new IllegalStateException(var9);
}
}
說明
1.SpringBoot的啟動過程,實際上就是對ApplicationContext的初始化過程蜻展。
2.ApplicationContext創(chuàng)建后立刻為其設(shè)置Environmen喉誊,并由ApplicationContextInitializer對其進一步封裝。
3.通過SpringApplicationRunListener在ApplicationContext初始化過程中各個時點發(fā)布各種廣播事件纵顾,并由ApplicationListener負責接收廣播事件伍茄。
4.初始化過程中完成IoC的注入,包括通過@EnableAutoConfiguration導入的各種自動配置類施逾。
5.初始化完成前調(diào)用ApplicationRunner和CommandLineRunner的實現(xiàn)類敷矫。