在 Spring MVC 中,DispatcherServlet 是前端控制器,它接收 HTTP 請求并将請求分發給正确的處理程式。具體的邏輯如下:
- 接收 HTTP 請求。
DispatcherServlet 的入口方法是 doService(),它接收 HTTP 請求,執行個體化 HttpServletRequest 和 HttpServletResponse 對象,并将它們傳遞給 doDispatch() 方法:
protected void doService(HttpServletRequest request, HttpServletResponse response) throws Exception {
// ...
doDispatch(request, response);
// ...
}
- 根據請求的 URL 找到對應的處理程式。
在 doDispatch() 方法中,DispatcherServlet 首先需要找到與請求 URL 比對的處理程式。這個任務由 HandlerMapping 接口及其實作類完成。HandlerMapping 會解析請求 URL,并查找與之比對的處理程式。最常用的實作類是 RequestMappingHandlerMapping,它會解析 @RequestMapping 注解,将 URL 映射到對應的處理程式。
protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception {
// ...
HandlerExecutionChain mappedHandler = null;
mappedHandler = this.handlerMapping.getHandler(request);
// ...
}
- 調用處理程式。
找到處理程式後,DispatcherServlet 就需要執行它了。這個任務由 HandlerAdapter 接口及其實作類完成。HandlerAdapter 會根據處理程式的類型和參數資訊來調用處理程式。
protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception {
// ...
HandlerAdapter handlerAdapter = getHandlerAdapter(mappedHandler.getHandler());
ModelAndView mv = handlerAdapter.handle(request, response, mappedHandler.getHandler());
// ...
}
- 根據處理程式傳回的視圖名或視圖對象找到對應的視圖。
處理程式執行完畢後,通常會傳回一個 ModelAndView 對象,其中包含視圖名或視圖對象。DispatcherServlet 需要根據這個資訊找到對應的視圖。這個任務由 ViewResolver 接口及其實作類完成。ViewResolver 會根據視圖名或視圖對象,查找并傳回對應的視圖。
protected void render(ModelAndView mv, HttpServletRequest request, HttpServletResponse response) throws Exception {
// ...
View view;
if (mv.isReference()) {
// We need to resolve the view name.
view = resolveViewName(mv.getViewName(), mv.getModelInternal(), locale, request);
// ...
} else {
// No need to lookup: the ModelAndView object contains the actual View object.
view = mv.getView();
// ...
}
// ...
}
- 渲染視圖并将結果傳回給用戶端。
最後,DispatcherServlet 需要将視圖渲染後的結果傳回給用戶端。這個任務由視圖本身完成。視圖通常會将渲染結果寫入到 HttpServletResponse 對象中,然後 DispatcherServlet 将其發送給用戶端。
protected void render(ModelAndView mv, HttpServletRequest request, HttpServletResponse response) throws Exception {
// ...
view.render(mv.getModelInternal(), request, response);
// ...
}
總之,DispatcherServlet 是 Spring MVC 的核心元件,它實作了前端控制器模式,負責接收 HTTP 請求,将其分發給正确的處理程式,并将處理結果渲染為視圖傳回給用戶端。
請求流程圖
上述流程圖描述了一個完整的請求過程,包括以下步驟:
- 用戶端發送請求到 DispatcherServlet。
- DispatcherServlet 擷取請求的 HandlerExecutionChain。
- DispatcherServlet 擷取 HandlerAdapter。
- HandlerAdapter 調用 Handler 處理請求。
- Handler 傳回 ModelAndView。
- DispatcherServlet 擷取 ViewResolver。
- ViewResolver 解析視圖。
- View 渲染視圖。
- DispatcherServlet 傳回響應給用戶端。