【SpringBoot】源碼學習筆記(二)

【開始Run】

//計時器,當前線程的信息
StopWatch stopWatch = new StopWatch();
stopWatch.start();


//上下文
ConfigurableApplicationContext context = null;
//存儲異常信息
Collection<SpringBootExceptionReporter> exceptionReporters = new ArrayList();
//設置headless屬性
this.configureHeadlessProperty();
//獲取、啓動監聽器,SpringApplicationRunListener配置來源於springboot的spring.factories
SpringApplicationRunListeners listeners = this.getRunListeners(args);
listeners.starting();

Collection exceptionReporters;
try {

//初始化默認應用參數
    ApplicationArguments applicationArguments = new DefaultApplicationArguments(args);

//根據監聽器和默認應用參數,準備spring所需要的的環境
    ConfigurableEnvironment environment = this.prepareEnvironment(listeners, applicationArguments);
    this.configureIgnoreBeanInfo(environment);

//打印banner
    Banner printedBanner = this.printBanner(environment);

//創建應用上下文環境,區分不同的環境 [servlet、webflux、普通應用]
    context = this.createApplicationContext();

//異常報告
    exceptionReporters = this.getSpringFactoriesInstances(SpringBootExceptionReporter.class, new Class[]{ConfigurableApplicationContext.class}, context);

//準備上下文,這裏面涉及到了Spring相關的知識
    this.prepareContext(context, environment, listeners, applicationArguments, printedBanner);

----------------------------------------------------prepareContext()--------------------------------------------------------

//將環境綁定到上下文
context.setEnvironment(environment);
//配置上下文bean的生成器和資源加載器
postProcessApplicationContext(context);
//爲上下文采用所有初始化器
applyInitializers(context);
//觸發監聽器的contextPrepared事件
listeners.contextPrepared(context);
//記錄啓動的日誌
if (this.logStartupInfo) {
   logStartupInfo(context.getParent() == null);
   logStartupProfileInfo(context);
}
// Add boot specific singleton beans 增加特殊的單例bean
ConfigurableListableBeanFactory beanFactory = context.getBeanFactory();
beanFactory.registerSingleton("springApplicationArguments", applicationArguments);
if (printedBanner != null) {
   beanFactory.registerSingleton("springBootBanner", printedBanner);
}
if (beanFactory instanceof DefaultListableBeanFactory) {
   ((DefaultListableBeanFactory) beanFactory)
         .setAllowBeanDefinitionOverriding(this.allowBeanDefinitionOverriding);
}
// Load the sources 加載所有資源
Set<Object> sources = getAllSources();
Assert.notEmpty(sources, "Sources must not be empty");
load(context, sources.toArray(new Object[0]));
//監聽器觸發contextLoaded事件
listeners.contextLoaded(context);

----------------------------------------------------prepareContext()--------------------------------------------------------

//刷新上下文
    this.refreshContext(context);

依次點進去,可以找到更深層的AbstractApplicationContext.refresh方法,這裏也涉及到Spring相關的知識

----------------------------------------------------AbstractApplicationContext.refresh()-------------------------------------------

//contextd的設置:啓動日期、當前狀態、初始化環境等
this.prepareRefresh();
//創建一個bean工廠,去註冊bean:定義、解析、處理和註冊
ConfigurableListableBeanFactory beanFactory = this.obtainFreshBeanFactory();
//準備bean工廠
this.prepareBeanFactory(beanFactory);
try {
//註冊scope 如request、session
    this.postProcessBeanFactory(beanFactory);
//調用所有bean工廠處理bean
    this.invokeBeanFactoryPostProcessors(beanFactory);
//bean的攔截操作
    this.registerBeanPostProcessors(beanFactory);
//國際化的操作
    this.initMessageSource();
//廣播事件
    this.initApplicationEventMulticaster();
//處理特殊的bean,如tomcat
    this.onRefresh();
//註冊監聽器
    this.registerListeners();
//完成bean工廠的初始化
    this.finishBeanFactoryInitialization(beanFactory);
//完成刷新
    this.finishRefresh();
} catch (BeansException var9) {
    if (this.logger.isWarnEnabled()) {
        this.logger.warn("Exception encountered during context initialization - cancelling refresh attempt: " + var9);
    }
    this.destroyBeans();
    this.cancelRefresh(var9);
    throw var9;
} finally {
    this.resetCommonCaches();
}

----------------------------------------------------AbstractApplicationContext.refresh()-------------------------------------------

//刷新之後的操作
    this.afterRefresh(context, applicationArguments);

//停止計時器
    stopWatch.stop();

//日誌輸出
    if (this.logStartupInfo) {
        (new StartupInfoLogger(this.mainApplicationClass)).logStarted(this.getApplicationLog(), stopWatch);
    }

//啓動監聽器

    listeners.started(context);

//執行所有 Runner 運行器
    this.callRunners(context, applicationArguments);

}catch (Throwable ex) {
    handleRunFailure(context, ex, exceptionReporters, listeners);
    throw new IllegalStateException(ex);
}

try {

//發佈應用上下文就緒事件
   listeners.running(context);
}
catch (Throwable ex) {
   handleRunFailure(context, ex, exceptionReporters, null);
   throw new IllegalStateException(ex);
}
return context;

【備註】

項目基於SpringBoot2.1.6

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章