Springboot啟動流程
- 初始化各種屬性,載入成物件
讀取環境屬性(Environment)
系統配置(spring.factories)
引數(Arguments、application.properties)
- 建立Spring容器物件ApplicationContext,載入各種配置
- 在容器建立前,透過監聽器機制,應對不同階段載入資料、更新資料的要求
- 容器初始化過程中追加各種功能,例如統計時間、輸出日誌等
第一步啟動來,run方法
進入run方法
primarySource屬性指的就是啟動類Springboot30StartupApplication,接下來再進入run方法
這是new了一個物件,載入各種配置資訊,初始化各種配置物件,然後呼叫了run這個方法初始化容器,接下來進入SpringApplication這個方法
這個方法裡呼叫了自己的構造方法,傳了一個resourceLoader(資源載入器),點選this進入構造方法
第一行是把傳進來的resourceLoader初始化成了成員變數(資源載入器),方便後續本方法和其他的方法使用;
第二行斷言,判斷一下primarySource是不是null;
第三行是把可變引數primarySource去重轉換成了集合型別的物件儲存到成員變數中
第四行的方法進去看看
這個方法是判斷並返回web應用的容器型別
第五行的方法是從SpringFactories的配置中獲得springboot系統引導註冊初始化的資訊,
進入方法
第1行先建立了一個BootstrapRegistryInitializer的集合;
第2行透過getSpringFactoriesInstances的方法針對Bootstrapper.class獲得了SpringFactoriesInstances的資訊,裡面進行了一系列的設定然後放入集合
第3行又透過getSpringFactoriesInstances的方法針對BootstrapRegistryInitializer.class獲得的資訊也加入了集合,進入這個方法
還有有一個方法,再進入
第1行拿到類載入器
第2行,初始化了一個集合,把要載入的所有東西提取出來,得到要載入所有東西的名稱
第3行,根據這個名稱,建立對應的例項,得到了所有的例項物件
第4行,對例項物件進行了排序
第5行,返回例項
第六行 設定初始化資訊,又使用到了getSpringFactoriesInstances方法,這回載入的是ApplicationContextInitializer.class的資訊
這只是這個spring.factories裡的,其他的檔案裡也可能有
第七行 設定監聽器,還是呼叫了getSpringFactoriesInstances方法,這回載入的是ApplicationListener.class的資訊(自定義的監聽器可以做很多的事情)
別忘了在spring.factories裡配置上
第八行 初始化了引導類的類名資訊(備用的)
接下來看run方法,初始化容器,得到一個ApplicationContext物件
第一行建立秒錶(StopWatch),是的,就是一個計時器
第二行啟動了計時器開始計時了,後面在第十八行停止的
這個就是計時器的反饋時間,看程式碼可知,springboot沒有把之前讀取檔案的時間算在內。
第三行建立的是系統引導資訊對應的上下文物件
第四行宣告瞭一個物件
第五行進入這個方法
這個方法裡系統級的設定了一個屬性,模擬輸入輸出訊號,避免出現因缺少外設導致的訊號傳輸失敗,進而引發錯誤(模擬顯示器,鍵盤,滑鼠...)
第1行是設定"java.awt.headless"這個值
第2行是設定方法裡面的引數,前面的是取了"java.awt.headless"這個值,後面是如果沒取到就用this.headless的值,如果去取到了,就用取到的值
其實就是配置了java.awt.headless = true
第六行獲取當前註冊的所有監聽器
第七行監聽器執行了對應的操作步驟
第九行拿引數
第十行將前期讀取的資料載入成了一個環境物件,用來描述資訊
第十一行做了一個配置,備用
第十二行初始化啟動圖示
第十三行建立容器物件,根據前期配置的容器型別進行判定並建立
第十四行設定應用啟動的啟動模式
第十五行對容器進行設定,引數來源於前期的設定
第十六行重新整理容器環境
第十七行重新整理完畢後做的後處理
第十八行計時器關閉
第十九行是判斷這個logStartupInfo是否為true(預設是true)
第二十行是透過判斷以後,建立一個啟動資訊的日誌物件,記錄了mainApplicationClass的啟動資訊
第二十一行監聽器執行了對應的操作步驟
第二十二行呼叫了執行器
第三十行監聽器執行了對應的操作步驟
整個方法所有的核心就是context = this.createApplicationContext();前面是建立容器前的各項引數準備工作,後面是把準備好的引數放到容器裡