SpringBoot執行原理-run方法


SpringBoot執行原理-run方法

每個Spring Boot項目都有一個主程序啟動類,在主程序啟動類中有一個啟動項目的main()方法,在該方法中通過執行SpringApplication.run()即可啟動整個Spring Boot程序。
問題:那么SpringApplication.run()方法到底是如何做到啟動Spring Boot項目的呢?
下面我們查看run()方法內部的源碼,核心代碼具體如下:

image-20211024125702161

從上述源碼可以看出,SpringApplication.run()方法內部執行了兩個操作,分別是SpringApplication實例的初始化創建和調用run()啟動項目,這兩個階段的實現具體說明如下:

1.SpringApplication實例的初始化創建

查看SpringApplication實例對象初始化創建的源碼信息,核心代碼具體如下 :

image-20211024130255885

image-20211024130304945

從上述源碼可以看出,SpringApplication的初始化過程主要包括4部分,具體說明如下。

  • this.webApplicationType=WebApplicationType.deduceFromClasspath()用於判斷當前webApplicationType應用的類型deduceFromClasspath()方法用於查看Classpath類路徑下是否存在某個特征類,從而判斷當前webApplicationType類型是SERVLET應用(Spring 5之前的傳統MVC應用)還是REACTIVE應用(Spring 5開始出現的WebFlux交互式應用)

  • this.setInitializers(this.getSpringFactoriesInstances(ApplicationContextInitializer.class))用於SpringApplication應用的初始化器設置。在初始化器設置過程中,會使用Spring類加載器SpringFactoriesLoader從META-INF/spring.factories類路徑下的META-INF下的spring.factores文件中獲取所有可用的應用初始化器ApplicationContextInitializer。

  • this.setListeners(this.getSpringFactoriesInstances(ApplicationListener.class))用於SpringApplication應用的監聽器設置。監聽器設置的過程與上一步初始化器設置的過程基本一樣,也是使用SpringFactoriesLoader從META-INF/spring.factories類路徑下的META-INF下的spring.factores文件中獲取所有可用的監聽器類ApplicationListener。

  • this.mainApplicationClass = this.deduceMainApplicationClass()
    用於推斷並設置項目main()方法啟動的主程序啟動類

2.項目的初始化啟動

分析完(new SpringApplication(primarySources)).run(args)源碼前一部分SpringApplication實例對象的初始化創建后,查看run(args)方法執行的項目初始化啟動過程,核心代碼具體如下:

image-20211024130215507

image-20211024130229871

從上述源碼可以看出,項目初始化啟動過程大致包括以下部分:

第一步:獲取並啟動監聽器。this.getRunListeners(args)和listeners.starting()方法主要用於獲取SpringApplication實 例初始化過程中初始化的SpringApplicationRunListener監聽器並運行。

第二步:根據SpringApplicationRunListeners以及參數來准備環境this.prepareEnvironment(listeners, applicationArguments)方法主要用於對項目運行環境進 行預設置,同時通過this.configureIgnoreBeanInfo(environment)方法排除一些不需要的運行環境。

第三步:創建Spring容器。根據webApplicationType進行判斷, 確定容器類型,如果該類型為SERVLET類型,會通過反射裝載 對應的字節碼,也就是AnnotationConfigServletWebServerApplicationContext,接着使用之前 初始化設置的context(應用上下文環境)、environment(項目運行環境)、listeners(運行監聽 器)、applicationArguments(項目參數)和printedBanner(項目圖標信息)進行應用上下文的組 裝配置,並刷新配置。

第四步:Spring容器前置處理。這一步主要是在容器刷新之前的准備動作。設置容器環境,包括各種變量等等,其中包含一個非常關鍵的操 作:將啟動類注入容器,為后續開啟自動化配置奠定基礎。

第五步:刷新容器。開啟刷新spring容器,通過refresh方法對整個IOC容器的初始化(包括bean資源的定位,解析,注冊等 等),同時向JVM運行時注冊一個關機鈎子,在JVM關機時會關閉這個上下文,除非當時它已經關閉。

第六步:Spring容器后置處理。擴展接口,設計模式中的模板方法,默認為空實現。如果有自定義需求,可以重寫該方法。比如打印一些啟 動結束log,或者一些其它后置處理。

第七步:發出結束執行的事件。獲取EventPublishingRunListener監聽器,並執行其started方法,並且將創建的Spring容器傳進去 了,創建一個ApplicationStartedEvent事件,並執行ConfigurableApplicationContext 的publishEvent方法,也就是說這里是在Spring容器中發布事件,並不是在SpringApplication中發布 事件,和前面的starting是不同的,前面的starting是直接向SpringApplication中的監聽器發布啟 動事件。

第八步:執行Runners。用於調用項目中自定義的執行器XxxRunner類,使得在項目啟動完成后立即執行一些特定程序。其中, Spring Boot提供的執行器接口有ApplicationRunner 和CommandLineRunner兩種,在使用時只需要 自定義一個執行器類實現其中一個接口並重寫對應的run()方法接口,然后Spring Boot項目啟動后會立 即執行這些特定程序 。

通過一個Spring Boot執行流程圖,讓大家更清晰的知道Spring Boot的整體執行流程和主要啟動階段:

image-20211024130712833


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM