一、靜態run方法受限建立一個SpringApplication實例,而後調用其run方法web
SpringApplication實例化,會作:spring
·根據classpath裏面是否存在某個特徵類(org.springframework.web.context.ConfigurableWebApplicationContext)來決定是否應該建立一個爲Web應用使用的ApplicationContext類型,仍是應該建立一個標準Standalone應用使用的使用的ApplicationContext類型,仍是應該建立一個標準Standalone應用使用的ApplicationContext類型。
·使用SpringFactoriesLoader在應用的classpath中查找並加載全部可用的ApplicationContextInitializer。
·使用SpringFactoriesLoader在應用的classpath中查找並加載全部可用的ApplicationListener。
·推斷並設置main方法的定義類app
二、run方法執行開始,首先遍歷執行全部經過SpringFactoriesLoader能夠查找到並加載的SpringApplicationRunListener,調用它們的started()方法框架
三、建立並配置當前SpringBoot應用將要使用的Environment(包括配置要使用的PropertySource以及Profile)。
四、遍歷調用全部SpringApplicationRunListener的environmentPrepared()的方法
五、若是SpringApplication的showBanner屬性被設置爲true,則打印bannerspa
六、根據用戶是否明確設置了applicationContextClass類型以及初始化階段的推斷結果,決定該爲當前SpringBoot應用建立什麼類型的ApplicationContext並建立完成,而後根據條件決定是否添加ShutdownHook,決定是否使用自定義的BeanNameGenerator,決定是否使用自定義的ResourceLoader,固然,最重要的,將以前準備好的Environment設置給建立好的ApplicationContext使用。
七、ApplicationContext建立好以後,SpringApplication會再次藉助Spring-FactoriesLoader,查找並加載classpath中全部可用的ApplicationContext-Initializer,而後遍歷調用這些ApplicationContextInitializer的initialize(applicationContext)方法來對已經建立好的ApplicationContext進行進一步的處理。
八、遍歷調用全部SpringApplicationRunListener的contextPrepared()方法接口
九、最核心的一步,將以前經過@EnableAutoConfiguration獲取的全部配置以及其餘形式的IoC容器配置加載到已經準備完畢的ApplicationContext。事件
十、遍歷調用全部SpringApplicationRunListener的contextLoaded()方法開發
十一、調用ApplicationContext的refresh()方法,完成IoC容器可用的最後一道工序。
十二、查找當前ApplicationContext中是否註冊有CommandLineRunner,若是有,則遍歷執行它們。
1三、正常狀況下,遍歷執行SpringApplicationRunListener的finished()方法、(若是整個過程出現異常,則依然調用全部SpringApplicationRunListener的finished()方法,只不過這種狀況下會將異常信息一併傳入處理)it
去除事件通知點後,整個流程以下:io
SpringApplicationRunListener
SpringApplicationRunListener是一個只有SpringBoot應用的main方法執行過程當中接收不一樣執行時點事件通知的監聽者。基本沒什麼常見的場景須要本身實現一個Spring-ApplicationRunListener,即便SpringBoot默認也只是實現了一個org.spring-framework.boot.context.event.EventPublishingRunListener,用於在SpringBoot啓動的不一樣時點發布不一樣的應用事件類型(ApplicationEvent)
ApplicationListener
Spring框架對Java中實現的監聽者模式的一種框架實現,這裏惟一值得着重強調的是,對於初次接觸SpringBoot,但對Spring框架自己又沒有過多接觸的開發者來講,可能會將這個名字與SpringApplicationRunListener混淆
若是咱們要爲SpringBoot應用添加自定義的ApplicationListener,有兩種方式:
1)經過SpringApplication.addListeners(..)或者SpringApplication.setListeners(..)方法添加一個或者多個自定義的ApplicationListener;
2)藉助SpringFactoriesLoader機制,在META-INF/spring.factories文件添加配置
ApplicationContextInitializer
ApplicationContextInitializer也是Spring框架原有的概念,這個類的主要目的就是在ConfigurableApplicationContext類型(或者子類型)的ApplicationContext作refresh以前,容許咱們對ConfigurableApplicationContext的實例作進一步的設置或者處理
通常狀況下咱們基本不會須要自定義一個ApplicationContext-Initializer,即便SpringBoot框架默認也只是註冊了三個實現。若是咱們真的須要自定義一個ApplicationContextInitializer,那麼只要像上面這樣,經過SpringFactoriesLoader機制進行配置,或者經過SpringApplication.addInitializers(..)設置便可
CommandLineRunner
屬於SpringBoot應用特定的回調擴展接口
須要你們關注的其實就兩點:
1)全部CommandLineRunner的執行時點在SpringBoot應用的Application-Context徹底初始化開始工做以後(能夠認爲是main方法執行完成以前最後一步)。
2)只要存在於當前SpringBoot應用的ApplicationContext中的任何Command-LineRunner,都會被加載執行(無論你是手動註冊這個CommandLineRunner到IoC容器,仍是自動掃描進去的)
與其餘幾個擴展點接口類型類似,建議CommandLineRunner的實現類使用@org.springframework.core.annotation.Order進行標註或者實現org.springframework.core.Ordered接口,便於對它們的執行順序進行調整,這其實十分重要,咱們不但願順序不當的CommandLineRunner實現類阻塞了後面其餘CommandLineRunner的執行。 CommandLineRunner是很好的擴展接口,你們能夠重點關注