SpringBoot入坑指南之五:應用啓動流程分析

概述

Spring Boot框架帶來一個Web應用啓動的重大變化。 Java的Web應用部署都是經過容器,如:Tomcat、JBoss、Weblogic、Undertow等,通常都是將Java的Web應用構建成war、ear包再部署到相關的容器中。 Spring Boot帶來了另一種方式,就是能夠將Web應用構建Jar包直接經過java命令啓動,簡化了應用的部署啓動。這種啓動方式底層技術並無實際的變化,而是經過內嵌容器的方式取代外部容器,好比:spring-boot-starter-web默認使用Tomcat內嵌容器,你也能夠選擇使用其餘內嵌容器。 在這篇文章裏面主要是以前閱讀了一些Spring Boot的啓動源碼,對Spring Boot啓動流程做了一些簡單的梳理。java

Spring Boot應用啓動方式

上文說到,Spring Boot的Web應用能夠構建Jar包直接啓動,即Spring Boot應用能夠經過main方法直接啓動,應用啓動入口代碼以下:web

/**
 * @author: cent
 * @email: 292462859@qq.com
 * @date: 2019/2/9.
 * @description:
 */
@SpringBootApplication
public class Application {

    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}

能夠發現,Spring Boot應用啓動入口代碼很是簡單,經過SpringApplication.run(Class<?> primarySource, String... args)方法啓動,那麼這個方法裏面做用作了什麼處理呢,下文主要就是對這個方法的源碼進行簡單的梳理~spring

Spring Boot應用啓動解析

啓動入口方法

Spring Boot啓動核心方法代碼以下,增長了簡單註釋,下文會對每一步驟進行簡單解釋:app

public ConfigurableApplicationContext run(String... args) {
        //1.初始化計時器
        StopWatch stopWatch = new StopWatch();
        //2.計時器啓動
        stopWatch.start();
        //Spring上下文對象
        ConfigurableApplicationContext context = null;
        //異常通知者列表
        Collection<SpringBootExceptionReporter> exceptionReporters = new ArrayList();
        //3.設置系統配置java.awt.headless
        this.configureHeadlessProperty();
        //4.獲取全部啓動時監聽器
        SpringApplicationRunListeners listeners = this.getRunListeners(args);
        //5.啓動監聽器
        listeners.starting();
         //定義異常通知者列表
        Collection exceptionReporters;
        try {
            //6.初始化應用啓動參數
            ApplicationArguments applicationArguments = new DefaultApplicationArguments(args);
            //7.準備環境變量
            ConfigurableEnvironment environment = this.prepareEnvironment(listeners, applicationArguments);
            //8.設置spring.beaninfo.ignore配置
            this.configureIgnoreBeanInfo(environment);
            //9.打印Banner
            Banner printedBanner = this.printBanner(environment);
            //10.建立上下文對象
            context = this.createApplicationContext();
            //11.獲取Spring異常報告者Bean列表
            exceptionReporters = this.getSpringFactoriesInstances(SpringBootExceptionReporter.class, new Class[]{ConfigurableApplicationContext.class}, context);
            //12.準備上下文對象
            this.prepareContext(context, environment, listeners, applicationArguments, printedBanner);
            //13.刷新上下文對象
            this.refreshContext(context);
            //14.刷新上下文對象後續工做
            this.afterRefresh(context, applicationArguments);
            //15.中止計時
            stopWatch.stop();
            //16.打印啓動信息
            if (this.logStartupInfo) {
                (new StartupInfoLogger(this.mainApplicationClass)).logStarted(this.getApplicationLog(), stopWatch);
            }
            // 17.執行啓動時監聽器started方法
            listeners.started(context);
            //18.執行ApplicationRunner和CommandLineRunner
            this.callRunners(context, applicationArguments);
        } catch (Throwable var10) {
            //處理運行異常
            this.handleRunFailure(context, var10, exceptionReporters, listeners);
            throw new IllegalStateException(var10);
        }

        try {
            //19.執行啓動時監聽器running方法
            listeners.running(context);
            return context;
        } catch (Throwable var9) {
            //處理運行異常
            this.handleRunFailure(context, var9, exceptionReporters, (SpringApplicationRunListeners)null);
            throw new IllegalStateException(var9);
        }
    }

啓動流程解釋

進一步閱讀啓動源碼,梳理Spring Boot應用啓動流程以下圖,下圖對每一個步驟進行簡單分析並說明,詳細的代碼邏輯須要看一下源碼。框架

Spring Boot啓動流程圖

尾巴

上面的內容是我的閱讀源碼分析的結果,可能存在錯誤之處,歡迎指正。上面的分析結果還比較表層,若是須要深刻了解Spring Boot啓動原理,建議深刻研究一下里面的源碼。less

相關文章
相關標籤/搜索