以 Spring MVC 啟動 Servlet 為例,其應用上下文為 ServletWebServerApplicationContext,繼承了 GenericWebApplicationContext 的大部分方法,主要重寫了 postProcessBeanFactory()、refresh() ...
以 Spring MVC 啟動 Servlet 為例,其應用上下文為 ServletWebServerApplicationContext,繼承了 GenericWebApplicationContext 的大部分方法,主要重寫了 postProcessBeanFactory()、refresh()、onRefresh()、finishRefresh()、onClose() 方法。
啟動流程
由 refresh() 可知,重寫方法的執行順序為:postProcessBeanFactory()、onRefresh()、finishRefresh()。
1、postProcessBeanFactory()
- 添加後置處理器 WebApplicationContextServletContextAwareProcessor
- 忽略自動裝配以來介面 ServletContextAware
- 註冊 web 應用的作用域
2、onRefresh()
- 調用父類的 onRefresh() 方法
- 創建 Web 伺服器
Spring 容器中會載入 @Configuration 註解的配置類 ServletWebServerFactoryConfiguration,它會按條件註入不同的 web 伺服器工廠類:Tomcat/Jetty/Undertow,預設條件下,可以註入 TomcatServletWebServerFactory, name 為 tomcatServletWebServerFactory。
onRefresh() 創建 Web 伺服器時,首先從 BeanFactory 獲取 ServletWebServerFactory 類型的 Bean,即上述的 TomcatServletWebServerFactory。利用這個工廠類的方法public WebServer getWebServer(ServletContextInitializer... initializers)
來創建 TomcatWebServer,這個方法主要就是為 TomcatWebServer 創建 Tomcat 實例。此外,註意其入參 ServletContextInitializer 是函數式介面,可以將其方法作為參數傳入,初始化 TomcatWebServer 時,調用 Tomcat.start() 啟動 Server,以非同步的方式執行該函數介面的實現類,即執行 onStartup() 方法。
創建 Tomcat 實例,是和 Tomcat 啟動相關的內容,也就是創建 Tomcat 相關的組件的過程,比如 Server、Service、Connector、Engine、Host、Context、Wrapper 、Lifecycle 等組件。
Tomcat 將在這一步完成初始化的工作,其生命周期狀態變化為:NEW
->INITIALIZING
->INITIALIZED
,INITIALIZED
表示已經初始化的狀態。
3、finishBeanFactoryInitialization(beanFactory)
從 BeanFactory 獲取 name 為 requestMappingHandlerMapping 的 Bean,並初始化這個 Bean,過程中執行其實現的介面方法 InitializingBean.afterPropertiesSet(),該方法遍歷所有可用的 Bean,找到 @Controller 或者 @RequestMapping 註解的類,利用反射技術,遍歷出這些類的方法及其請求 URL 的映射關係進行緩存。
4、finishRefresh()
真正完成啟動 Tomcat,其生命周期狀態變化為:INITIALIZED
->STARTING_PREP
->STARTING
->STARTED
,即表示啟動成功。
請求流程
Tomcat 接收請求
- 瀏覽器輸入http://127.0.0.1:8080/test,地址127.0.0.1、埠號8080的 Endpoint 接收到請求,並將請求交給處理器 Processor 處理;
- 處理器將請求通過適配器 CoyoteAdapter,從緩存 Mapper 中找到路徑映射,從而依次找到 Engine->Host->Context->Wrapper
- 先調用過濾器鏈 FilterChain,過濾之後,執行 Servlet
- 執行完畢,再將響應 Response 依次返回
DispatcherServlet
Tomcat 作為 Servlet 容器,負責監聽 Socket 請求,並將請求映射、並轉交給具體的 Servlet 進行處理。Spring MVC 中非常重要的,負責請求處理調度的類 DispatcherServlet,就是 Servlet 的一個實現,所以在 Spring MVC 應用中,是使用 DispatcherServlet 來處理請求的,其實現 Servlet 的繼承關係如下圖:
DispatcherServlet 獲取到請求後的執行流程