1. 程式人生 > >Spring MVC請求處理具體流程

Spring MVC請求處理具體流程

這裡寫圖片描述

// 前端控制器分派方法
protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception {
        HttpServletRequest processedRequest = request;
        HandlerExecutionChain mappedHandler = null;
        int interceptorIndex = -1;

        try {
            ModelAndView mv;
            boolean
errorView = false; try { // 檢查是否是請求是否是multipart(如檔案上傳),如果是將通過MultipartResolver解析 processedRequest = checkMultipart(request); // 步驟2、請求到處理器(頁面控制器)的對映,通過HandlerMapping進行對映 mappedHandler = getHandler(processedRequest, false); if
(mappedHandler == null || mappedHandler.getHandler() == null) { noHandlerFound(processedRequest, response); return; } // 步驟3、處理器適配,即將我們的處理器包裝成相應的介面卡(從而支援多種型別的處理器) HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler()); // 304 Not Modified快取支援
// 此處省略具體程式碼 // 執行處理器相關的攔截器的預處理(HandlerInterceptor.preHandle) // 此處省略具體程式碼 // 步驟4、由介面卡執行處理器(呼叫處理器相應功能處理方法) mv = ha.handle(processedRequest, response, mappedHandler.getHandler()); // Do we need view name translation? if (mv != null && !mv.hasView()) { mv.setViewName(getDefaultViewName(request)); } // 執行處理器相關的攔截器的後處理(HandlerInterceptor.postHandle) // 此處省略具體程式碼 } catch (ModelAndViewDefiningException ex) { logger.debug("ModelAndViewDefiningException encountered", ex); mv = ex.getModelAndView(); } catch (Exception ex) { Object handler = (mappedHandler != null ? mappedHandler.getHandler() : null); mv = processHandlerException(processedRequest, response, handler, ex); errorView = (mv != null); } // 步驟5 步驟6、解析檢視並進行檢視的渲染 // 步驟5 由ViewResolver解析View(viewResolver.resolveViewName(viewName, locale)) // 步驟6 檢視在渲染時會把Model傳入(view.render(mv.getModelInternal(), request, response);) if (mv != null && !mv.wasCleared()) { render(mv, processedRequest, response); if (errorView) { WebUtils.clearErrorRequestAttributes(request); } } else { if (logger.isDebugEnabled()) { logger.debug("Null ModelAndView returned to DispatcherServlet with name '" + getServletName() + "': assuming HandlerAdapter completed request handling"); } } // 執行處理器相關的攔截器的完成後處理(HandlerInterceptor.afterCompletion) // 此處省略具體程式碼 catch (Exception ex) { // Trigger after-completion for thrown exception. triggerAfterCompletion(mappedHandler, interceptorIndex, processedRequest, response, ex); throw ex; } catch (Error err) { ServletException ex = new NestedServletException("Handler processing failed", err); // Trigger after-completion for thrown exception. triggerAfterCompletion(mappedHandler, interceptorIndex, processedRequest, response, ex); throw ex; } finally { // Clean up any resources used by a multipart request. if (processedRequest != request) { cleanupMultipart(processedRequest); } } }

核心架構的具體流程步驟如下:
1、 首先使用者傳送請求——>DispatcherServlet,前端控制器收到請求後自己不進行處理,而是委託給其他的解析器進行處理,作為統一訪問點,進行全域性的流程控制;
2、 DispatcherServlet——>HandlerMapping, HandlerMapping將會把請求對映為HandlerExecutionChain物件(包含一個Handler處理器(頁面控制器)物件、多個HandlerInterceptor攔截器)物件,通過這種策略模式,很容易新增新的對映策略;
3、 DispatcherServlet——>HandlerAdapter,HandlerAdapter將會把處理器包裝為介面卡,從而支援多種型別的處理器,即介面卡設計模式的應用,從而很容易支援很多型別的處理器;
4、 HandlerAdapter——>處理器功能處理方法的呼叫,HandlerAdapter將會根據適配的結果呼叫真正的處理器的功能處理方法,完成功能處理;並返回一個ModelAndView物件(包含模型資料、邏輯檢視名);
5、 ModelAndView的邏輯檢視名——> ViewResolver, ViewResolver將把邏輯檢視名解析為具體的View,通過這種策略模式,很容易更換其他檢視技術;
6、 View——>渲染,View會根據傳進來的Model模型資料進行渲染,此處的Model實際是一個Map資料結構,因此很容易支援其他檢視技術;
7、 返回控制權給DispatcherServlet,由DispatcherServlet返回響應給使用者,到此一個流程結束。