Spring MVC 作為 Java Web 開發的基石框架,其運行機制涉及容器啟動初始化、Handler 映射註冊、請求分發處理等核心環節。本文將從源碼層面,系統梳理 Spring MVC 的三大核心流程:對象初始化(Bean 裝載)、Controller 方法與 URL 映射綁定、請求到達 Controller 方法前的完整邏輯鏈路。
初始化工作集中在 org.springframework.web.servlet.FrameworkServlet 的 initServletBean 方法中,最終委派給 AbstractApplicationContext 的 refresh() 方法完成 Bean 的載入與註冊。
FrameworkServlet.initServletBean() → AbstractApplicationContext.refresh() → obtainFreshBeanFactory()DefaultListableBeanFactory 作為 Bean 容器,Bean 定義信息存儲在 beanDefinitionMap (ConcurrentHashMap) 中。registerBeanDefinition(String beanName, BeanDefinition beanDefinition) 中實現,支持覆蓋策略與線程安全。這一階段為後續 Web 組件(Controller、Interceptor、ViewResolver 等)的實例化奠定基礎。
映射綁定工作在 spring-webmvc.jar 內完成,核心類為 org.springframework.web.servlet.handler.AbstractHandlerMethodMapping。
InitializingBean 接口,容器啟動時自動調用 afterPropertiesSet() → initHandlerMethods()。@RequestMapping 註解的 Controller 方法,建立 URL → HandlerMethod 映射關係。AbstractHandlerMethodMapping 的成員變量 urlMap 中,供運行時快速查找。initHandlerMethods 為 protected 修飾,允許子類擴展自定義映射策略。
請求處理入口為 DispatcherServlet.doDispatch(HttpServletRequest, HttpServletResponse),完整邏輯可拆解為四大階段:
調用 AbstractHandlerMethodMapping.getHandlerInternal() → lookupHandlerMethod()。
核心邏輯:
- 從 urlMap 獲取直接匹配的映射列表;
- 若無直接匹配,遍歷所有映射進行模式匹配;
- 使用 MatchComparator 排序選出最佳匹配;
- 若存在歧義(多個最佳匹配),拋出 IllegalStateException。
返回封裝了 Controller 實例、Method、參數信息 的 HandlerMethod 對象。
遍歷 HandlerExecutionChain 中的 HandlerInterceptor,依次調用 preHandle()。若任一返回 false,中斷流程並觸發 afterCompletion。
委派給 RequestMappingHandlerAdapter.invokeHandlerMethod(),進而調用 InvocableHandlerMethod.invokeForRequest()。
關鍵動作:
- 解析請求參數,構建參數數組 args[];
- 反射調用目標方法;
- 封裝返回值為 ModelAndView。
逆序調用攔截器 postHandle(),最後由 render() 進行視圖解析與渲染,或直接返回響應數據。
| 類/接口 | 核心職責 |
|---|---|
DispatcherServlet | 前端控制器,統籌請求分發全流程 |
AbstractHandlerMethodMapping | 維護 URL 到 HandlerMethod 的映射註冊表 |
HandlerMethod | 封裝 Controller Bean、Method、MethodParameter[] 等調用元數據 |
RequestMappingHandlerAdapter | 適配器模式,負責實際調用 HandlerMethod 並處理參數綁定、返回值處理 |
InvocableHandlerMethod | 封裝方法調用邏輯,含參數解析、反射調用、返回值處理 |
Spring MVC 運行原理體現了「約定優於配置」與「策略模式」的設計哲學:
1. 啟動階段完成 Bean 裸載與 Handler 映射註冊,構建靜態路由表;
2. 運行階段通過 DispatcherServlet 串聯攔截器鏈、HandlerAdapter、視圖解析器,形成可擴展的請求處理管道。
理解這一原理,有助於排查映射衝突、參數綁定失敗、攔截器不生效等疑難雜症,也為自定義擴展(如統一異常處理、簽名驗證攔截器)提供理論依據。