javascript
带你从源码了解SpringBoot启动流程
從哪入手?
相信很多人嘗試讀過Spring Boot的源碼,但是始終沒有找到合適的方法。那是因為你對Spring Boot的各個組件、機制不是很了解,研究起來就像大海撈針。
至于從哪入手不是很簡單的問題嗎,當然主啟動類了,即是標注著@SpringBootApplication注解并且有著main()方法的類,如下一段代碼:
@SpringBootApplication public class AnnotationDemoApplication {public static void main(String[] args) {SpringApplication.run(AnnotationDemoApplication.class, args);} }源碼如何切分?
SpringApplication中的靜態run()方法并不是一步完成的,最終執行的源碼如下:
//org.springframework.context.ConfigurableApplicationContext public static ConfigurableApplicationContext run(Class<?>[] primarySources, String[] args) {return new SpringApplication(primarySources).run(args);}如何創建SpringApplication?
創建即是new對象了,DEBUG跟進代碼,最終執行的SpringApplication構造方法如下圖:
設置應用類型
這個過程非常重要,直接決定了項目的類型,應用類型分為三種,都在WebApplicationType這個枚舉類中,如下:
判斷的依據很簡單,就是加載對應的類,比如加載了DispatcherServlet等則會判斷是Servlet的web程序。源碼如下:
static WebApplicationType deduceFromClasspath() {if (ClassUtils.isPresent(WEBFLUX_INDICATOR_CLASS, null) && !ClassUtils.isPresent(WEBMVC_INDICATOR_CLASS, null)&& !ClassUtils.isPresent(JERSEY_INDICATOR_CLASS, null)) {return WebApplicationType.REACTIVE;}for (String className : SERVLET_INDICATOR_CLASSES) {if (!ClassUtils.isPresent(className, null)) {return WebApplicationType.NONE;}}return WebApplicationType.SERVLET;}這里我引入了spring-boot-starter-web,肯定是Servlet的web程序。
設置初始化器(Initializer)
初始化器ApplicationContextInitializer是個好東西,用于IOC容器刷新之前初始化一些組件,比如ServletContextApplicationContextInitializer。
那么如何獲取初始化器呢?跟著上圖中的代碼進入,在SpringApplication中的如下圖中的方法:
相對重要的就是第一步獲取初始化器的名稱了,這個肯定是全類名了,詳細源碼肯定在loadFactoryNames()方法中了,跟著源碼進入,最終調用的是#SpringFactoriesLoader.loadSpringFactories()方法。
loadSpringFactories()方法就不再詳細解釋了,其實就是從類路徑META-INF/spring.factories中加載ApplicationContextInitializer的值。
設置監聽器(Listener)
監聽器(ApplicationListener)這個概念在Spring中就已經存在,主要用于監聽特定的事件(ApplicationEvent),比如IOC容器刷新、容器關閉等。
Spring Boot擴展了ApplicationEvent構建了SpringApplicationEvent這個抽象類,主要用于Spring Boot啟動過程中觸發的事件,比如程序啟動中、程序啟動完成等。
監聽器如何獲取?從源碼中知道其實和初始化器(ApplicationContextInitializer)執行的是同一個方法,同樣是從META-INF/spring.factories文件中獲取。
總結
SpringApplication的構建都是為了run()方法啟動做鋪墊,構造方法中總共就有幾行代碼,最重要的部分就是設置應用類型、設置初始化器、設置監聽器。
?
總結
以上是生活随笔為你收集整理的带你从源码了解SpringBoot启动流程的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: SpringBoot启动流程是怎样的
- 下一篇: Nginx 和 Zuul 的区别