springboot啓動流程(五)建立ApplicationContext

全部文章

http://www.javashuo.com/article/p-uvudtich-bm.htmlhtml

 

正文

springboot在啓動過程當中將會根據當前應用的類型建立對應的ApplicationContext。本文內容較短,承上啓下,將不會涉及太多具體的內容,主要在於爲後續的ioc內容構建一個ApplicationContext實例。react

咱們簡單回顧一下,在第二篇文章介紹SpringApplication的run方法web

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方法spring

 

咱們跟進createApplicationContextspringboot

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);
}

該方法的邏輯較爲簡單,走兩個分支app

1)自定義ApplicationContext的實現類this

2)根據當前應用的類型webApplicationType來匹配對應的ApplicationContext,是servlet、reactive或者非web應用spa

 

總結

建立ApplicationContext的實例對象較爲簡單,就是選擇實現類,反射獲取類的實例對象。至於實現類是本身設置的,仍是經過當前應用類型匹配的由開發人員去選擇,不過默認狀況下都是由類型去推斷出來的。code

本文雖短,可是後續的文章也基本都是圍繞着本文構建的ApplicationContext,這說明spring的核心也基本都包含在這個ApplicationContext當中了。htm

相關文章
相關標籤/搜索