首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 綜合教學

Spring MVC 啟動流程深度解析:從 web.xml 到 DispatcherServlet 工作原理

     編輯:Java 綜合教學

Spring MVC 啟動流程深度解析:從 web.xml 到 DispatcherServlet 工作原理

本文基於 Spring 源碼視角,系統梳理 Spring MVC 容器啟動全鏈路:Web 容器初始化 → ContextLoaderListener 創建根上下文 → DispatcherServlet 初始化 Web 上下文 → 請求分發處理流程。掌握核心類繼承體系、關鍵模板方法、上下文層級關係,為源碼閱讀與疑難排查打基礎。

一、Web 容器初始化標準流程 (Servlet Spec)

  1. 實例化 ServletContextListener 實現類
  2. 調用 contextInitialized(ServletContextEvent)
  3. 實例化 Filter 並調用 init()
  4. 實例化 Servlet (load-on-startup > 0) 並調用 init()
  5. 應用正式接收請求

二、web.xml 雙核心配置

<!-- 1. 根上下文加載器 -->
<listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>classpath:applicationContext-*.xml</param-value>
</context-param>

<!-- 2. 前端控制器 -->
<servlet>
    <servlet-name>dispatcherServlet</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <init-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath:spring-mvc.xml</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
    <servlet-name>dispatcherServlet</servlet-name>
    <url-pattern>/</url-pattern>
</servlet-mapping>

三、ContextLoaderListener:根上下文構建者

  • 實現 ServletContextListener,代理模式包裝 ContextLoader
  • contextInitialized() → ContextLoader.initWebApplicationContext()
  • 核心步驟:
    1. 創建 XmlWebApplicationContext (根上下文)
    2. 加載 contextConfigLocation 指定的 Bean 定義 (Service、DAO、DataSource、事務管理器等)
    3. refresh() 完成 Bean 實例化、依賴注入、AOP 代理、後置處理器執行
    4. 將根上下文綁定到 ServletContext 屬性 WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE
  • 失敗即拋異常,容器啟動中止

四、DispatcherServlet 初始化繼承鏈

HttpServletBean (抽象)
    ↓ init() 解析 init-param → setBeanProperties()
FrameworkServlet (抽象)
    ↓ initWebApplicationContext() 創建/刷新 WebApplicationContext
    ↓ initFrameworkServlet() 留給子類擴展
DispatcherServlet (具體)
    ↓ onRefresh() 初始化九大組件 (HandlerMapping, HandlerAdapter, ViewResolver...)

關鍵模板方法

五、兩個上下文的父子關係

  • 根上下文 (ContextLoaderListener):業務層 Bean (Service、Repository、DataSource、TransactionManager) — 全局單例
  • Web 上下文 (DispatcherServlet):表現層 Bean (Controller、HandlerMapping、ViewResolver、Interceptor) — 每個 DispatcherServlet 一個
  • 可見性:Web 上下文可訪問根上下文 Bean;根上下文不可訪問 Web 上下文 Bean
  • 配置隔離:contextConfigLocation 分離,避免重複掃描/衝突

六、DispatcherServlet 九大核心組件

在 initStrategies() 中按順序初始化(可自定義覆蓋):

  1. MultipartResolver — 文件上傳解析
  2. LocaleResolver — 國際化區域解析
  3. ThemeResolver — 主題解析
  4. HandlerMapping — URL 映射到 Handler (Controller 方法)
  5. HandlerAdapter — 統一調用 Handler 適配器
  6. HandlerExceptionResolver — 異常處理
  7. RequestToViewNameTranslator — 默認視圖名翻譯
  8. ViewResolver — 視圖名解析為 View 實例
  9. FlashMapManager — 重導向屬性傳遞

七、請求處理核心流程 (doDispatch)

1. 獲取 Handler (HandlerMapping)
2. 獲取 HandlerAdapter
3. 執行攔截器 preHandle
4. HandlerAdapter.handle() → 調用 Controller 方法
5. 返回 ModelAndView
6. 執行攔截器 postHandle
7. 異常時 HandlerExceptionResolver 解析
8. 視圖解析 (ViewResolver) → View
9. View.render() 輸出響應
10. 執行攔截器 afterCompletion

Spring MVC 請求處理流程圖

八、源碼閱讀技巧總結

  1. 找入口:web.xml → ContextLoaderListener / DispatcherServlet
  2. 看繼承鏈:模板方法模式定義骨架,具體類填充細節
  3. 關注 refresh():IoC 容器啟動核心,Bean 生命週期在此
  4. 追策略初始化:initStrategies() 揭示擴展點
  5. 畫時序圖:請求處理流程圖化,理清攔截器/異常/視圖交互
理解啟動流程,是排查「Bean 未注入」、「Controller 不生效」、「事務不生效」等疑難雜症的前提。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved
類方法職責
HttpServletBeaninit()將 <init-param> 綁定到 Bean 屬性,模板方法模式
FrameworkServletinitWebApplicationContext()創建 WebApplicationContext,建立父子關係 (父=根上下文),調用 refresh()
FrameworkServletinitFrameworkServlet()空實現,子類擴展點
DispatcherServletonRefresh()初始化策略組件:initStrategies()