在我的文章 裡曾經提到,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應用入口,SpringApplication.run開始。
SpringApplication註釋清楚寫明,在它的邏輯的第三步,是刷新Application Context,加載所有的單例Bean:
在org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext的onRefresh方法裡,第152行代碼會觸發Tomcat服務器的創建。
org.springframework.beans.factory.support.AbstractBeanFactory會觸發根據bean的定義實例化bean的行為:
在org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory裡執行Bean的population和initialize的動作,bean名稱為tomcatServletWebServerFactory。
bean實例化完畢之後,執行org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory的postProcessBeforeInitialization,這樣我們在文章開頭實現的修改Tomcat默認端口號的鉤子就會被調用到:
至於Tomcat服務器本身的實現,我們觀察我們的SpringBoot應用通過Maven打出來的jar包裡,在目錄BOOT-INF文件夾的lib內:
- tomcat-embed-core-8.5.31.jar
- tomcat-embed-el-8.5.31.jar
- tomcat-embed-websocket-8.5.31.jar
閱讀更多 汪子熙SAP 的文章