SpringBoot原始碼分析(二)啟動原理
阿新 • • 發佈:2020-03-30
**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