淺談SpringApplication啓動原理

我們知道,如果不需要特殊的配置,只需要在main方法裡調用SpringApplicatio.run()方法即可啟動Spring Boot應用:

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

作為深入原理的第一篇,我們先來看下Spring Boot應用是怎麼啟動的。

SpringBoot簡介

SpringBoot是由Pivotal團隊提供的全新框架,其設計目的是用來簡化新Spring應用的初始搭建以及開發過程。該框架使用了特定的方式來進行配置,從而使開發人員不再需要定義樣板化的配置。通過這種方式,Boot致力於在蓬勃發展的快速應用開發領域(rapid application development)成為領導者。

SpringBoot並不是要成為Spring平臺裡面眾多“Foundation”層項目的替代者。SpringBoot的目標不在於為已解決的問題域提供新的解決方案,而是為平臺帶來另一種開發體驗,從而簡化對這些已有技術的使用。

SpringBoot主要有如下核心特點:

  • 包含執行所需的一切的可執行jar包。包含了運行所需的一切,包括內嵌應用服務器等,並打包為一個可執行jar文件部署,這點在微服務概念裡非常重要。
  • 約定大於配置理念的完美踐行,自動配置模塊
  • 提供各種各樣的starter簡化初始配置過程
  • 提供各種擴展機制等等
淺談SpringApplication啟動原理

可以看出,這是一個複合註釋,其中

@SpringBootConfiguration代表了SpringBoot的配置類,除了測試時有些區別,大體上就是Spring標準@Configuration的替代品。

@EnableAutoConfiguration用於啟動SpringBoot的自動配置機制,這是SpringBoot的核心特色之一,自動對各種機制進最大可能的進行配置。可根據引入的jar包對可能需要的各種機制進進行默認配置。

淺談SpringApplication啟動原理

@ComponentScan是Spring原來就有的註釋,用於對指定的路徑進行掃描,並將其中的@Configuration配置類加載。

淺談SpringApplication啟動原理

SpringApplication啟動流程

SpringApplication的啟動過程非常複雜,下面是在調用SpringApplication.run方法之後啟動的關鍵動作:

淺談SpringApplication啟動原理

既然要了解SpringApplication的啟動流程,第一步當然是進入源碼裡看看嘍:

淺談SpringApplication啟動原理

淺談SpringApplication啟動原理

第一步,初始化監聽器

這裡會初始化Spring Boot自帶的監聽器,以及添加到SpringApplication的自定義監聽器。

初始化監聽器的調用關係很深,為了節省篇幅,就不貼源碼了,稍後用專門的文章細聊。

第二步,發佈ApplicationStartedEvent事件

到這一步,Spring Boot會發佈一個ApplicationStartedEvent事件。如果你想在這個時候執行一些代碼可以通過實現ApplicationListener接口實現;

下面是ApplicationListener接口的定義,注意這裡有個

  1. public interface ApplicationListener extends EventListener

例如,你想監聽ApplicationStartedEvent事件,你可以這樣定義:

  1. public class ApplicationStartedListener implements ApplicationListener

然後通過SpringApplication.addListener(..)添加進去即可。

第三步,裝配參數和環境

在這一步,首先會初始化參數,然後裝配環境,確定是web環境還是非web環境。

第四步,發佈ApplicationEnvironmentPreparedEvent事件

準確的說,這個應該屬於第三步,在裝配完環境後,就觸發ApplicationEnvironmentPreparedEvent事件。如果想在這個時候執行一些代碼,可以訂閱這個事件的監聽器,方法同第二步。

第五步,打印Banner

看過Spring Boot實例教程 - 自定義Banner的同學會很熟悉,啟動的Banner就是在這一步打印出來的。

第六步,創建ApplicationContext

這裡會根據是否是web環境,來決定創建什麼類型的ApplicationContext,ApplicationContext不要多說了吧,不知道ApplicationContext是啥的同學,出門左轉補下Spring基礎知識吧。

第七步,裝配Context

這裡會設置Context的環境變量、註冊Initializers、beanNameGenerator等。

第八步,發佈ApplicationPreparedEvent事件

這裡放在第七步會更準確,因為這個是在裝配Context的時候發佈的。

值得注意的是:這裡是假的,假的,假的,源碼中是空的,並沒有真正發佈ApplicationPreparedEvent事件。不知道作者這麼想的???

第九步,註冊、加載等

註冊springApplicationArguments、springBootBanner,加載資源等。

第十步,發佈ApplicationPreparedEvent事件

注意,到這裡才是真正發佈了ApplicationPreparedEvent事件。這裡和第八步好讓人誤解。

第十一步,refreshContext

裝配context beanfactory等非常重要的核心組件。

第十二步,afterRefreshContext

這裡會調用自定義的Runners,不知道Runners是什麼的同學,請參考Spring Boot官方文檔 - SpringApplication

第十三步,發佈ApplicationReadyEvent事件

最後一步,發佈ApplicationReadyEvent事件,啟動完畢,表示服務已經可以開始正常提供服務了。通常我們這裡會監聽這個事件來打印一些監控性質的日誌,表示應用正常啟動了。添加方法同第二步。

注意:如果啟動失敗,這一步會發布ApplicationFailedEvent事件。

到這裡,Spring Boot啟動的一些關鍵動作就介紹完了。


分享到:


相關文章: