所有文章
https://www.cnblogs.com/lay2017/p/11478237.html
正文
springboot在啟動過程中將會根據當前應用的類型創建對應的ApplicationContext。本文內容較短,承上啟下,將不會涉及太多具體的內容,主要在於為后續的ioc內容構建一個ApplicationContext實例。
我們簡單回顧一下,在第二篇文章介紹SpringApplication的run方法
public ConfigurableApplicationContext run(String... args) { // 聲明一個Context容器 ConfigurableApplicationContext context = null; // 獲取監聽器 SpringApplicationRunListeners listeners = getRunListeners(args); // 調用監聽器的啟動 listeners.starting(); try { // 創建並配置Environment(這個過程會加載application配置文件) ConfigurableEnvironment environment = prepareEnvironment(listeners, applicationArguments); // 根據應用類型創建對應的Context容器 context = createApplicationContext(); // 刷新Context容器之前的准備 prepareContext(context, environment, listeners, applicationArguments, printedBanner); // 刷新Context容器 refreshContext(context); // 刷新Context容器之后處理 afterRefresh(context, applicationArguments); // Context容器refresh完畢發布 listeners.started(context); // 觸發Context容器refresh完以后的執行 callRunners(context, applicationArguments); } catch (Throwable ex) {} try { // Context啟動完畢,Runner運行完畢發布 listeners.running(context); } catch (Throwable ex) {} return context; }
邏輯步驟中,創建Environment之后,刷新ApplicationContext之前,我們還需要做的一件事就是創建ApplicationContext實例,也就是createApplicationContext方法
我們跟進createApplicationContext
public static final String DEFAULT_SERVLET_WEB_CONTEXT_CLASS = "org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext"; public static final String DEFAULT_REACTIVE_WEB_CONTEXT_CLASS = "org.springframework.boot.web.reactive.context.AnnotationConfigReactiveWebServerApplicationContext"; public static final String DEFAULT_CONTEXT_CLASS = "org.springframework.context.annotation.AnnotationConfigApplicationContext"; protected ConfigurableApplicationContext createApplicationContext() { // 先判斷有沒有指定的實現類 Class<?> contextClass = this.applicationContextClass; // 如果沒有,則根據應用類型選擇 if (contextClass == null) { try { switch (this.webApplicationType) { case SERVLET: contextClass = Class.forName(DEFAULT_SERVLET_WEB_CONTEXT_CLASS); break; case REACTIVE: contextClass = Class.forName(DEFAULT_REACTIVE_WEB_CONTEXT_CLASS); break; default: contextClass = Class.forName(DEFAULT_CONTEXT_CLASS); } } catch (ClassNotFoundException ex) { throw new IllegalStateException( "Unable create a default ApplicationContext, " + "please specify an ApplicationContextClass", ex); } } // 通過反射獲取對應類的實例 return (ConfigurableApplicationContext) BeanUtils.instantiateClass(contextClass); }
該方法的邏輯較為簡單,走兩個分支
1)自定義ApplicationContext的實現類
2)根據當前應用的類型webApplicationType來匹配對應的ApplicationContext,是servlet、reactive或者非web應用
總結
創建ApplicationContext的實例對象較為簡單,就是選擇實現類,反射獲取類的實例對象。至於實現類是自己設置的,還是通過當前應用類型匹配的由開發人員去選擇,不過默認情況下都是由類型去推斷出來的。
本文雖短,但是后續的文章也基本都是圍繞着本文構建的ApplicationContext,這說明spring的核心也基本都包含在這個ApplicationContext當中了。
