1. 程式人生 > >SpringBoot原始碼分析(二)啟動原理

SpringBoot原始碼分析(二)啟動原理

**Springboot的jar啟動方式,是通過IOC容器啟動 帶動了Web容器的啟動** **而Springboot的war啟動方式,是通過Web容器(如Tomcat)的啟動 帶動了IOC容器相關的啟動** # 一、不可不說的Web容器(如Tomcat) 不管是jar啟動還是war包啟動,都繞不開web容器相關。先了解這個怎麼工作的,以Tomcat為例, 看看Springboot 怎麼來自動裝配tomcat 相關的元件? ## 1.1 相關類 相關包org.springframework.boot.autoconfigure.web,在springboot的自動配置包的web下(自動配置功能都在這個autoconfigure包下)。 ![](https://img2020.cnblogs.com/blog/1085149/202003/1085149-20200329230457316-1692115889.png) embedded(內嵌)裡面四個類一個A四B,一個: EmbeddedWebServerFactoryCustomizerAutoConfiguration(內嵌web容器工廠自定義定製器裝配類) 四個具體容器相關: JettyWebServerFactoryCustomizer、NettyWebServerFactoryCustomizer、TomcatWebServerFactoryCustomizer、UndertowWebServerFactoryCustomizer 一個自動配置類+四個常用web容器定製器 ## 1.2.工作流程 以Tomcat定製器切入,斷點落在構造器上,啟動。 總結出它的工作流程: 1.啟動=》2.createWebServer=》 3.拿TomcatServletWebServerFactory(tomcatWeb容器工廠)=》 4.拿WebServerFactoryCustomizer(工廠定製器) 也就是拿工廠定製器獲取工廠,再拿工廠獲取web容器,這麼個流程 ## 1.3.具體工作 可以仔細看下相關工廠是如何配置建立容器執行的 TomcatServletWebServerFactory的建立Tomcat方法 ```java public WebServer getWebServer(ServletContextInitializer... initializers) { Tomcat tomcat = new Tomcat(); File baseDir = (this.baseDirectory != null) ? this.baseDirectory : createTempDir("tomcat"); tomcat.setBaseDir(baseDir.getAbsolutePath()); Connector connector = new Connector(this.protocol); tomcat.getService().addConnector(connector); customizeConnector(connector); tomcat.setConnector(connector); tomcat.getHost().setAutoDeploy(false); configureEngine(tomcat.getEngine()); for (Connector additionalConnector : this.additionalTomcatConnectors) { tomcat.getService().addConnector(additionalConnector); } prepareContext(tomcat.getHost(), initializers); return getTomcatWebServer(tomcat); } ``` 建立Tocmat類並設定相關這些元件,應該很熟悉(以後出Tomcat原始碼分析)。 TomcatWebServerFactoryCustomizer的customize定製方法,通過類serverProperties配置檔案設定工廠的屬性 # 二、SpringBoot的jar啟動方式 來自: ```java public static void main(String[] args) { SpringApplication.run(StudySpringbootApplication.class, args); } ``` 開啟原始碼: ```java public static ConfigurableApplicationContext run(Class[] primarySources, String[] args) { return new SpringApplication(primarySources).run(args); } ``` 其實兩步,一步建立SpringApplication ,一步run執行。 建立類做的事情比較簡單,主要包括判斷web應用型別、用SpringFactories技術從 spring.factories 檔案裡獲取ApplicationContextInitializer 對應類和ApplicationListener,最後獲取當前應用的啟動類的類物件。 ## 2.1 run方法 ```java public ConfigurableApplicationContext run(String... args) { //StopWatch是記錄時間的工具,為了列印那句SpringBoot啟動耗時的 StopWatch stopWatch = new StopWatch(); stopWatch.start(); ConfigurableApplicationContext context = null; Collection