SpringBoot面試題:SpringBoot應用啓動嵌入Tomcat伺服器的奧祕

在我的文章 裡曾經提到,Spring Boot應用會自動啟動一個嵌入的Tomcat服務器實例,默認監聽端口號為8080。那麼這個行為Spring Boot框架是如何做到的呢?背後有什麼秘密?

其實按照我上述文章介紹的辦法,可以很容易自己通過調試找到答案。

只需要在我們的Spring Boot里加入以下幾行代碼:

@Component

public class ServerPortCustomizer

implements WebServerFactoryCustomizer {

@Override

public void customize(ConfigurableWebServerFactory factory) {

factory.setPort(8089);

}

}

以調試方式運行Spring Boot應用,該斷點會自動觸發。

SpringBoot面試題:SpringBoot應用啟動嵌入Tomcat服務器的奧秘

觀察調用棧,我們從調用棧最外層,即我們的SpringBoot應用入口,SpringApplication.run開始。

SpringBoot面試題:SpringBoot應用啟動嵌入Tomcat服務器的奧秘

SpringApplication註釋清楚寫明,在它的邏輯的第三步,是刷新Application Context,加載所有的單例Bean:

SpringBoot面試題:SpringBoot應用啟動嵌入Tomcat服務器的奧秘

在org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext的onRefresh方法裡,第152行代碼會觸發Tomcat服務器的創建。

SpringBoot面試題:SpringBoot應用啟動嵌入Tomcat服務器的奧秘

org.springframework.beans.factory.support.AbstractBeanFactory會觸發根據bean的定義實例化bean的行為:

SpringBoot面試題:SpringBoot應用啟動嵌入Tomcat服務器的奧秘

在org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory裡執行Bean的population和initialize的動作,bean名稱為tomcatServletWebServerFactory。

SpringBoot面試題:SpringBoot應用啟動嵌入Tomcat服務器的奧秘

bean實例化完畢之後,執行org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory的postProcessBeforeInitialization,這樣我們在文章開頭實現的修改Tomcat默認端口號的鉤子就會被調用到:

SpringBoot面試題:SpringBoot應用啟動嵌入Tomcat服務器的奧秘

至於Tomcat服務器本身的實現,我們觀察我們的SpringBoot應用通過Maven打出來的jar包裡,在目錄BOOT-INF文件夾的lib內:

SpringBoot面試題:SpringBoot應用啟動嵌入Tomcat服務器的奧秘

  • tomcat-embed-core-8.5.31.jar
  • tomcat-embed-el-8.5.31.jar
  • tomcat-embed-websocket-8.5.31.jar
SpringBoot面試題:SpringBoot應用啟動嵌入Tomcat服務器的奧秘

SpringBoot面試題:SpringBoot應用啟動嵌入Tomcat服務器的奧秘


分享到:


相關文章: