Springboot 啟動詳解
1.前言
最近一直在看Springboot和springcloud代碼,看了將近20多天,對這兩個系統的認知總算是入了門。後續應該會有一個系列的文章,本文就先從Springboot的啟動入手.
2.容器初始化
上面的代碼是Springboot的入口,現在從run方法進去
點擊進來後到了這裏就會分成兩步
1.生成一個SpringApplication對象
2.調用生成的對象的run方法
【2.1】我們先看SpringApplication的構造器是如何生成一個SpringApplication對象
1.推斷程序類型,推斷規則在2.1.1
2.查找ApplicationContextInitializer的實現類,ApplicationContextInitializer是Spring框架的接口,在ApplicationContext的初始化之前,需要逐一調用ApplicationContextInitializer的實現類的initialize方法。
3.查找中ApplicationListener的實現類,Springboot大量的采用了事件監聽機制,ApplicationListener負責將監聽事件並廣播出去。後續我們會詳細講解
【2.1.1】判斷程序類型
至此SpringApplication構造初始化就完成了。
3.容器啟動
調用生成的對象的run方法
【3.1】記錄時間
Springboot內部記錄流程節點花費時間的工具類
【3.2】獲取ApplicationRunListener
這裏通過SpringApplicationRunListeners 封裝了多個SpringApplicationRunListener。在容器的啟動過程中,springboot將這個過程分為了五步
started(run方法執行的時候立馬執行;對應事件的類型是ApplicationStartedEvent)
environmentPrepared(ApplicationContext創建之前並且環境信息準備好的時候調用;對應事件的類型是ApplicationEnvironmentPreparedEvent)
contextPrepared(ApplicationContext創建好並且在source加載之前調用一次;沒有具體的對應事件)
contextLoaded(ApplicationContext創建並加載之後並在refresh之前調用;對應事件的類型是ApplicationPreparedEvent)
finished(run方法結束之前調用;對應事件的類型是ApplicationReadyEvent或ApplicationFailedEvent)
同時,SpringApplicationRunListener 只有一個實現類 EventPublishingRunListener,所以上述5個步驟的最終實現都會在 EventPublishingRunListener中。
我們看看start方法
這裏的 ApplicationStartedEvent 繼承 SpringApplicationEvent
再看publishEvent是如何把Event推送出去的
看到這邊,發現最後發送event的還是ApplicationListener
這裏一整套的封裝,就是為了這邊發送事件
【3.3】創建容器
【3.3.1】創建Environment
【3.3.2】創建容器
【3.3.3】SpringApplication的init
找到所有ApplicationContextInitializer的實現類,調用他們的initialize方法。
【3.3.4】加載mainsource到容器
【3.3.5】refresh,BeanFactory的設置,BeanFactoryPostProcessor接口的執行、BeanPostProcessor接口的執行、自動化配置類的解析、條件註解的解析、國際化的初始化
【3.4】容器創建之後
【3.4.1】Runer實現類
調用ApplicationRunner和CommandLineRunner的實現類
4.Springboot啟動的擴展
上述講了springboot的啟動流程,那如果我們想在啟動的時候自定義一些操作,可以考慮以下幾種方式。
【4.1】對容器的操作
實現 ApplicationContextInitializer 接口,重寫initialize方法
需要註意的是,這個bean需要在META-INF/spring.factories中註冊上才可以被掃描到
【4.2】監聽5大事件
實現 ApplicationListener
【4.3】實現 ApplicationRunner 或者 CommandLineRunner
以上,就是Springboot的啟動流程,裏面還有幾處細節,後續會慢慢更新
Springboot 啟動詳解