SpringMVC處理請求

HttpServletBean瀏覽器

HttpServletBean主要參與了建立工做,並無涉及請求的處理。緩存

FrameworkServlet服務器

FrameworkServlet的service方法裏添加了對PATCH的處理,並將全部須要本身處理的請求都集中到了processRequest方法進行統一處理,這和HttpServlet裏面根據request的類型將請求分配到各個不一樣的方法進行處理的過程正好相反。
processRequest方法裏主要的處理邏輯交給了doService,這是一個模板方法,在子類DispatcherServlet實現。app

DispatcherServlet異步

DispatcherServlet的doServic並無直接進行處理,而是交給了doDispatch進行具體的處理;在doDispatch處理前doServic作了一些事情,判斷是否是include請求,若是是則對request的Attribute作個快照備份,等doDispatch處理完以後進行還原。async

doDispatch的核心代碼
// 根據request找到Handler
mappedHandler = getHandler(processedRequest);
// 根據Handler找到對應的HandlerAdapter
HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler());
// 用HandlerAdapter處理Handler
mv = ha.handle(processedRequest, response, mappedHandler.getHandler());
// 處理上面的結果,包含找到View並渲染輸出給用戶
processDispatchResult(processedRequest, response, mappedHandler, mv, dispatchException);源碼分析

Handler:處理器,對應MVC中的Controller層,它能夠是類,也能夠是方法;標註了@RequestMapping的方法就是一個Handler。
HandlerMapping:用來查找Handler
HandlerAdapter:Spring MVC中的Handler能夠是任意的形式,只要能處理請求就OK,可是Servlet須要的處理方法的結構倒是固定的,都是以request和response爲參數的方法。HandlerAdapter讓固定的Servlet處理方法能夠調用靈活的Handler來處理請求。post

源碼分析:this

protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception {
    // 請求對象,若是是上傳請求會封裝爲上傳類型的request
    HttpServletRequest processedRequest = request;
    // 處理器鏈,包含處理器和Interceptor
    HandlerExecutionChain mappedHandler = null;
    // 是否是文件上傳
    boolean multipartRequestParsed = false;
    // 異步管理
    WebAsyncManager asyncManager = WebAsyncUtils.getAsyncManager(request);

    try {
        try {
            ModelAndView mv = null;
            // 異常對象
            Object dispatchException = null;
            try {    
                //若是是上傳請求,將request轉換爲MultipartHttpServletRequest,用到了MultipartResolver
                processedRequest = this.checkMultipart(request);
                multipartRequestParsed = processedRequest != request;
                // 根據request找處處理器鏈,其中包含與當前request相匹配的Interceptor和handler
                // Interceptor和Handler,執行時先調用Interceptor的preHandle方法,最後執行Handler
                // 返回的時候按相反的順序執行Interceptor的postHandle方法
                mappedHandler = this.getHandler(processedRequest);
                if (mappedHandler == null || mappedHandler.getHandler() == null) {
                    this.noHandlerFound(processedRequest, response);
                    return;
                }
                // 根據Handler找到對應的HandlerAdapter
                HandlerAdapter ha = this.getHandlerAdapter(mappedHandler.getHandler());
                /* 處理Get、Head請求的LastModified
                 * 當瀏覽器第一次跟服務器請求資源(GET、Head請求)時,
                 * 服務器在返回的請求頭裏面會包含一個Last-Modified的屬性,
                 * 表明本資源最後是何時修改的。
                 * 在瀏覽器之後發送請求時會同時發送以前接收到的LastModified,
                 * 服務器接收到帶Last-Modified的請求後會用其值和本身實際資源的最後修改時間作對比,
                 * 若是資源過時了則返回新的資源(同時返回新的Last-Modified),
                 * 不然直接返回304狀態碼錶示資源未過時,瀏覽器直接使用以前緩存的結果。
                 */
                String method = request.getMethod();
                boolean isGet = "GET".equals(method);
                if (isGet || "HEAD".equals(method)) {
                    long lastModified = ha.getLastModified(request, mappedHandler.getHandler());
                    if (this.logger.isDebugEnabled()) {
                        this.logger.debug("Last-Modified value for [" + getRequestUri(request) + "] is: " + lastModified);
                    }

                    if ((new ServletWebRequest(request, response)).checkNotModified(lastModified) && isGet) {
                        return;
                    }
                }
                /* 接下來依次調用相應Interceptor的preHandle、
                 * HandlerAdapter使用Handler處理請求,Controller就是在這個地方執行的,
                 * Handler處理完請求後,若是須要異步處理,則直接返回,
                 * 若是不須要異步處理,當view爲空時(如Handler返回值爲void),
                 * 設置默認view,而後執行相應Interceptor的postHandle。
                 */ 
                // 執行相應的Interceptor的preHandle 
                if (!mappedHandler.applyPreHandle(processedRequest, response)) {
                    return;
                }
                // HandlerAdapter使用Handler處理請求
                mv = ha.handle(processedRequest, response, mappedHandler.getHandler());
                // 若是須要異步處理直接返回
                if (asyncManager.isConcurrentHandlingStarted()) {
                    return;
                }
                // 當view爲空時,好比,Handler返回值爲void,根據request設置默認的view
                this.applyDefaultViewName(processedRequest, mv);
                // 執行相應Interceptor的方法
                mappedHandler.applyPostHandle(processedRequest, response, mv);
            } catch (Exception var20) {
                dispatchException = var20;
            } catch (Throwable var21) {
                dispatchException = new NestedServletException("Handler dispatch failed", var21);
            }
            // 處理返回結果。包括處理異常、渲染頁面、發出完成通知觸發Interceptor的afterCompletion
            this.processDispatchResult(processedRequest, response, mappedHandler, mv, (Exception)dispatchException);
        } catch (Exception var22) {
            this.triggerAfterCompletion(processedRequest, response, mappedHandler, var22);
        } catch (Throwable var23) {
            this.triggerAfterCompletion(processedRequest, response, mappedHandler, new NestedServletException("Handler processing failed", var23));
        }

    } finally {
        // 判斷是否執行異步請求
        if (asyncManager.isConcurrentHandlingStarted()) {
            if (mappedHandler != null) {
                mappedHandler.applyAfterConcurrentHandlingStarted(processedRequest, response);
            }
        // 刪除上傳請求的資源    
        } else if (multipartRequestParsed) {
            this.cleanupMultipart(processedRequest);
        }

    }
}
相關文章
相關標籤/搜索