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