DispatcherServlet的初始化與請求處理流程
初始化階段
-
Servlet 生命周期觸發:當 Web 容器(如 Tomcat)啟動時,根據注解/配置,DispatcherServlet 的
init()
方法被調用。 -
初始化 WebApplicationContext
- 根 WebApplicationContext:由
ContextLoaderListener
加載,包含 Service、DAO 等非 Web 層 Bean。 - DispatcherServlet 子上下文:專屬于 Servlet,包含 Controller、ViewResolver 等 Web 層 Bean,繼承根上下文。
- 根 WebApplicationContext:由
-
初始化策略組件
- HandlerMapping:將請求映射到處理器(Controller 方法),如
RequestMappingHandlerMapping
。 - HandlerAdapter:執行處理器方法,適配不同處理器類型,如
RequestMappingHandlerAdapter
。 - HandlerExceptionResolver:處理請求過程中拋出的異常。
- ViewResolver:解析邏輯視圖名到具體視圖(如 JSP、Thymeleaf)。
- LocaleResolver:解析客戶端區域信息(國際化)。
- ThemeResolver:解析主題信息。
- RequestToViewNameTranslator:請求到視圖名的默認轉換。
- FlashMapManager:管理 Flash 屬性(重定向時的臨時數據存儲)。
- MultipartResolver:處理文件上傳請求。
- HandlerMapping:將請求映射到處理器(Controller 方法),如
-
默認組件加載規則
- 按類型查找:從容器中查找對應類型的 Bean(如
ViewResolver
)。 - 默認策略:若未找到,加載
DispatcherServlet.properties
中定義的默認實現類。
- 按類型查找:從容器中查找對應類型的 Bean(如
請求處理階段
-
請求到達與分發:當 HTTP 請求到達時,Servlet 容器的
service()
方法觸發,最終調用 -
獲取處理器執行鏈(HandlerExecutionChain)
- HandlerMapping的作用:根據請求 URL 匹配對應處理器(Controller方法),并收集關聯攔截器(
HandlerInterceptor
)。 - 匹配優先級:
RequestMappingHandlerMapping
(基于@RequestMapping
)優先于BeanNameUrlHandlerMapping
。
- HandlerMapping的作用:根據請求 URL 匹配對應處理器(Controller方法),并收集關聯攔截器(
-
獲取處理器適配器(HandlerAdapter)
-
適配器模式:不同處理器(如基于注解的
@Controller
、傳統的Controller
接口)需要不同的適配器執行。 -
常用適配器:
RequestMappingHandlerAdapter
:處理@RequestMapping
方法。HttpRequestHandlerAdapter
:處理HttpRequestHandler
(如靜態資源處理)。SimpleControllerHandlerAdapter
:處理Controller
接口實現類。
-
-
執行處理器方法
- 參數解析與綁定:
HandlerMethodArgumentResolver
解析方法參數(如@RequestParam
、@RequestBody
)。 - 返回值處理:
HandlerMethodReturnValueHandler
處理返回值(如@ResponseBody
轉 JSON)。
- 參數解析與綁定:
-
視圖渲染
- ViewResolver:解析視圖名(如
"home"
)為View
對象(如InternalResourceView
)。 - View:渲染模型數據(如填充 JSP 中的
${message}
)。
- ViewResolver:解析視圖名(如
-
異常處理
- HandlerExceptionResolver:捕獲處理器方法或攔截器拋出的異常,生成錯誤視圖或狀態碼(如
@ExceptionHandler
)。 - 默認實現:
ExceptionHandlerExceptionResolver
(處理@ExceptionHandler
方法)、ResponseStatusExceptionResolver
(處理@ResponseStatus
注解)。
- HandlerExceptionResolver:捕獲處理器方法或攔截器拋出的異常,生成錯誤視圖或狀態碼(如
-
攔截器(Interceptor)的執行順序
- preHandle():請求處理前執行(如權限校驗)。
- postHandle():處理器方法執行后,視圖渲染前執行(如修改模型數據)。
- afterCompletion():整個請求完成后執行(如資源清理)。
HandlerMapping與HandlerAdapter的職責解析
HandlerMapping:請求與處理器的映射器
-
核心職責
-
請求路由:根據HTTP請求的URL、請求方法(GET/POST等)、請求頭等信息,找到對應的處理器(Handler)。
-
處理器鏈構建:返回一個
HandlerExecutionChain
對象,包含目標處理器及其關聯的攔截器(HandlerInterceptor
)。 -
多策略支持:支持不同類型的映射策略(如基于注解、基于XML配置、基于Bean名稱等)。
-
-
常見實現類
- RequestMappingHandlerMapping:處理
@RequestMapping
注解(包括@GetMapping
、@PostMapping
等衍生注解)。 - BeanNameUrlHandlerMapping:根據Bean名稱與URL匹配(如Bean名以
/
開頭)。 - SimpleUrlHandlerMapping: 通過XML或Java配置顯式映射URL到處理器(如靜態資源處理)。
- RequestMappingHandlerMapping:處理
-
工作流程
- 請求匹配:遍歷所有注冊的
HandlerMapping
,調用其getHandler()
方法,直到找到匹配的處理器。 - 攔截器綁定:將匹配的處理器與配置的攔截器組合成
HandlerExecutionChain
。 - 優先級控制:通過
Order
注解或實現Ordered
接口調整多個HandlerMapping
的執行順序。
- 請求匹配:遍歷所有注冊的
HandlerAdapter:處理器的適配執行器
-
核心職責
-
處理器適配:將不同類型的處理器(如
@Controller
、HttpRequestHandler
)統一適配為可執行的邏輯。 -
方法調用:反射調用處理器方法,處理參數綁定、返回值轉換等細節。
-
異常處理:捕獲處理器執行過程中的異常,轉換為統一的處理流程。
-
-
常見實現類
- RequestMappingHandlerAdapter:適配基于
@RequestMapping
的處理器方法(最常用)。 - HttpRequestHandlerAdapter:適配
HttpRequestHandler
接口(如處理靜態資源的ResourceHttpRequestHandler
)。 - SimpleControllerHandlerAdapter:適配實現
Controller
接口的傳統處理器。
- RequestMappingHandlerAdapter:適配基于
-
工作流程
- 適配器選擇:根據處理器類型選擇對應的
HandlerAdapter
。 - 參數解析:通過
HandlerMethodArgumentResolver
解析請求參數(如@RequestParam
、@RequestBody
)。 - 方法執行:反射調用處理器方法,獲取返回值。
- 返回值處理:通過
HandlerMethodReturnValueHandler
處理返回值(如@ResponseBody
轉JSON)。
- 適配器選擇:根據處理器類型選擇對應的
視圖解析與渲染
ViewResolver(視圖解析器)
- 作用:將控制器返回的 邏輯視圖名(如
"home"
)解析為具體的 View 對象。 - 核心方法:
View resolveViewName(String viewName, Locale locale)
。 - 實現類:
- InternalResourceViewResolver:解析 JSP、HTML 等內部資源視圖。
- ThymeleafViewResolver:解析 Thymeleaf 模板。
- ContentNegotiatingViewResolver:根據請求的媒體類型(如
Accept
頭)協商視圖。 - JsonViewResolver:返回 JSON 視圖(如結合
@ResponseBody
)。
View(視圖)
- 作用:負責將模型數據(
Model
)渲染為具體的響應內容(如生成 HTML、寫入 JSON)。 - 核心方法:
void render(Map<String, ?> model, HttpServletRequest request, HttpServletResponse response)
。 - 實現類:
- InternalResourceView:渲染 JSP 頁面。
- ThymeleafView:渲染 Thymeleaf 模板。
- MappingJackson2JsonView:將模型數據轉為 JSON 響應。
- AbstractPdfView:生成 PDF 文件。
視圖解析與渲染流程
- 控制器返回視圖名:控制器方法返回
String
類型的視圖名(如return "home";
)或ModelAndView
對象。 - DispatcherServlet 委托 ViewResolver 解析:
DispatcherServlet
遍歷所有注冊的ViewResolver
,調用resolveViewName()
方法,直到找到第一個非null
的View
對象。- 優先級控制:通過
Order
注解或實現Ordered
接口調整ViewResolver
的執行順序。
- 優先級控制:通過
- View 渲染模型數據:獲取
View
對象后,調用其render()
方法,將模型數據與響應結合: - 響應返回客戶端:最終生成的 HTML、JSON 或其他內容通過
HttpServletResponse
返回客戶端。
參數綁定與數據轉換
參數綁定
- 作用:將外部輸入(如 HTTP 請求參數、配置文件值)映射到方法參數或對象屬性。
- 場景:控制器方法通過
@RequestParam
綁定請求參數;配置文件通過@Value
注入屬性值;AOP切面中攔截方法參數進行修改驗證。
數據轉換
- 作用:將字符串或其他類型的輸入數據轉換為目標類型(如
String
→Date
)。 - 核心組件:
- Converter<S, T>:通用類型轉換接口(如
String
→Integer
)。 - Formatter<T>:面向區域(Locale)的格式化接口(如
Date
?String
)。 - ConversionService:統一管理所有轉換器,提供類型轉換服務。
- Converter<S, T>:通用類型轉換接口(如
Converter 與 Formatter
- Converter(類型轉換器):適用于通用的類型轉換邏輯,無需考慮區域(Locale)。
- Formatter(格式化器):需考慮區域化的格式化(如日期、貨幣)。
- 自動生效:Spring 在參數綁定時自動調用
ConversionService
完成轉換。
異常處理機制
核心組件與職責
- HandlerExceptionResolver:解析異常并生成錯誤視圖或響應,是異常處理的頂層接口。
- @ExceptionHandler:注解在方法上,標記該方法用于處理特定類型的異常(通常結合
@ControllerAdvice
)。 - @ControllerAdvice:定義全局異常處理類,集中處理多個控制器的異常。
- DefaultHandlerExceptionResolver:Spring 默認實現,處理標準 Spring MVC 異常。
- ResponseStatusExceptionResolver:根據
@ResponseStatus
注解設置 HTTP 狀態碼和錯誤信息。 - ExceptionHandlerExceptionResolver:處理
@ExceptionHandler
注解標記的方法,最常用的異常處理器。
異常處理流程
- 查找匹配的 @ExceptionHandler:在拋出異常的控制器類中查找
@ExceptionHandler
方法;若未找到,在@ControllerAdvice
全局類中查找。 - 遍歷 HandlerExceptionResolver鏈:Spring 內置的解析器按以下順序嘗試處理異常:
- ExceptionHandlerExceptionResolver:處理
@ExceptionHandler
方法。 - ResponseStatusExceptionResolver:處理
@ResponseStatus
注解。 - DefaultHandlerExceptionResolver:處理標準 Spring 異常。
- ExceptionHandlerExceptionResolver:處理
- 生成錯誤響應:
- 解析器返回
ModelAndView
(如錯誤頁面)或直接修改HttpServletResponse
(如設置狀態碼)。 - 若所有解析器均無法處理異常,由 Servlet 容器(如 Tomcat)返回默認錯誤頁(如 500 頁面)。
- 解析器返回