Spring Web MVC 的核心是 DispatcherServlet,它扮演前端控制器角色,統一接收 HTTP 請求並委派給下游組件處理。本文基於官方文檔 15.2 節,結合源碼關鍵點,梳理其核心工作流程與配置要點。
DispatcherServlet.doDispatch() 接收 HttpServletRequest/HttpServletResponse。MultipartResolver 解析。HandlerMapping 列表,根據 URL 找到 HandlerExecutionChain(含 Controller + 攔截器鏈)。HandlerAdapter 列表,找到支援該 Controller 的適配器(如 RequestMappingHandlerAdapter)。HandlerInterceptor.preHandle(),任一返回 false 中斷流程。ModelAndView。HandlerInterceptor.postHandle(),可修改模型或視圖。ViewResolver,將邏輯視圖名解析為具體 View 實例(JSP、Thymeleaf、JSON 等)。View.render(model, request, response) 輸出最終響應。HandlerInterceptor.afterCompletion(),釋放資源、記錄日誌等。| 組件 | 典型實現 | 配置方式 |
|---|---|---|
| HandlerMapping | RequestMappingHandlerMapping | <mvc:annotation-driven/> 自動註冊 |
| HandlerAdapter | RequestMappingHandlerAdapter | 同上自動註冊,支援 @RequestBody、@ResponseBody |
| ViewResolver | InternalResourceViewResolver (JSP) | 配置 prefix/suffix,或 ThymeleafViewResolver |
| MultipartResolver | StandardServletMultipartResolver | Servlet 3.0+ 容器自動支援,或 CommonsMultipartResolver |
| LocaleResolver | AcceptHeaderLocaleResolver | 可自定 Cookie/Session 策略 |
| ThemeResolver | FixedThemeResolver | 主題切換較少用,可忽略 |
<servlet>
<servlet-name>spring</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>spring</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
contextConfigLocation 指向 Spring MVC 配置檔;load-on-startup 確保容器啟動時初始化。
<beans xmlns="https://www.springframework.org/schema/beans"
xmlns:mvc="https://www.springframework.org/schema/mvc"
xmlns:context="https://www.springframework.org/schema/context"
xsi:schemaLocation="...">
<!-- 掃描 Controller -->
<context:component-scan base-package="com.example.controller"/>
<!-- 註解驅動:HandlerMapping + HandlerAdapter + 消息轉換器 -->
<mvc:annotation-driven/>
<!-- 視圖解析器 (JSP) -->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/views/"/>
<property name="suffix" value=".jsp"/>
</bean>
<!-- 靜態資源映射 -->
<mvc:resources mapping="/static/**" location="/static/"/>
</beans>
@RequestMapping 路徑、component-scan 包路徑、url-pattern 是否為 / 而非 /*。org.springframework.web DEBUG 日誌,觀察 HandlerMethodArgumentResolver 執行情況。ViewResolver 順序、邏輯視圖名拼寫、JSP 檔案實際路徑。DispatcherServlet 以「策略模式」組合 HandlerMapping、HandlerAdapter、ViewResolver 等介面,實現高度可擴展的請求處理管線。理解其流程與核心組件職責,是排查 Spring MVC 問題、進行深度定製的基礎。