SpringBoot啟動流程與源碼


  一 main方法作為程序的入口,執行SpringApplication.run(),傳入參數是啟動類的class對象@SpringBootApplication注解

二 run中首先new SpringApplication對象,然后調用該對象的run方法,返回是一個ConfigurableApplicationContext對象。

三 這里我們先看new SpringApplication的時候會進行什么操作,run方法隨后在看,這段代碼中的每一步依次來說:

  1.使用了Assert.notNull來判斷空值是一個良好的習慣,Assert類來自core的org.springframework.util包下,該包提供了很多工具類,之后會單獨有一篇介紹  spring提供給我們好用的工具類的文章。

  2.其中會deduceFromClasspath(deduce意為“推斷”)應用類型是servlet還是reactive

classPath中這三個最少有一個

並且這兩個全都有才是一個web應用

  3.getSpringFactoriesInstance(ApplicationContextInitiliazer.class)方法從spring-boot包下的"META-INF/spring.factories"路徑加載ClassLoader

該文件:

這種方式更容易看懂共有八個接口分別對應多個實現類:

其中只取key為ApplicationContextInitializer的value返回,該value是個List<String>,是實現了ApplicationContextInitializer接口的實現類名稱,以“,”分隔

然后將這些類進行加載,這些類指的是:

之后同樣的方式加載ApplicationListener接口的實現類:

 

 4.判定主程序是哪個類

 通過遍歷棧信息,找到調用main方法的類型,將其加載,賦值給變量mainApplicationClass

 四 SpringApplication的run方法

其中重要的邏輯都用黃色框圈了出來:

  1.加載所有的監聽器,和上述一樣,加載指定好的類都是根據spring.factories中的對應的監聽器,加載EventPublishingRunListener,之后調用該類的starting:

 

之后調用該類的starting方法,對之前加載的所有ApplicationListener根據事件類型進行廣播事件(multicastEvent):

  2.准備容器環境,會依據之前推斷(deduce)的應用類型返回對應的環境對象:   

 

  之后由監聽器執行enviromentPrepared方法,其中需要注意的是會有一個監聽器叫:ConfigFileApplicationListener,該接口的實現類會實際加載yml或.properties的配置文件:

  

  

  

隨后在執行ConfigFileApplicationLitener的postProcessEnviroment方法時,會加載factories的PropertySourceLoader對應的實現類:

來加載yml或.properties中的配置,至此,容器環境配置完成。

  3.創建容器上下文createApplicationContext(),也是依據之前的應用類型推斷結果:

  

  之后准備容器上下文:

  

  首先將創建的context中的enviroment全部替換為springApplication中剛剛創建的enviroment,然后向context中注冊beanfactory:

  

  然后用當前context作為參數,調用springApplication中所有的intilizer實現類執行,intilize方法,其中重點關注COnfigurationWaringsApplicationContextInitializer類的該方法:

  

  所有的listener執行contetxPrepared方法,之后向beanfacotry中注冊兩個參數,之后是load方法:

      創建了一個beanDefinitionLoader對象,該對象最主要支持了xml加載和annotated加載方式,加載所有source中的對象,這里只有一個主類,被@Component注解(注解繼承),將其注入到beanfactory中的beanDefinitionMap中

  

  在refreshContext中會加載所有的bean到beanFactory中:

    

    

  至此,就將所有的bean由容器來管理。


免責聲明!

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



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