SSM-SpringMVC-04:SpringMVC深入淺出理解HandleMapping(源碼刨析)

來源:互聯網
上載者:User

標籤:hex   ace   處理   gpo   很多   lin   mapped   集合   tps   

 

------------吾亦無他,唯手熟爾,謙卑若愚,好學若饑-------------

 

 

先從概念理解,從中央調度器,攜帶參數request,調度到HandleMapping處理器映射器,處理器映射器返回處理器執行鏈給中央調度器

 

我從底層走一遍,印證這個概念:

  1.都說是中央調度器的,所以先找到中央調度器DispatcherServlet

  2.從他裡面找到一個方法   ctrl+f 找(doDistch)

 

    protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception {        HttpServletRequest processedRequest = request;        HandlerExecutionChain mappedHandler = null;        boolean multipartRequestParsed = false;        WebAsyncManager asyncManager = WebAsyncUtils.getAsyncManager(request);        try {            try {                ModelAndView err = null;                Exception dispatchException = null;                try {                    processedRequest = this.checkMultipart(request);                    multipartRequestParsed = processedRequest != request;                    mappedHandler = this.getHandler(processedRequest);                    if(mappedHandler == null || mappedHandler.getHandler() == null) {                        this.noHandlerFound(processedRequest, response);                        return;                    }                    HandlerAdapter ex = this.getHandlerAdapter(mappedHandler.getHandler());                    String method = request.getMethod();                    boolean isGet = "GET".equals(method);                    if(isGet || "HEAD".equals(method)) {                        long lastModified = ex.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;                        }                    }                    if(!mappedHandler.applyPreHandle(processedRequest, response)) {                        return;                    }                    err = ex.handle(processedRequest, response, mappedHandler.getHandler());                    if(asyncManager.isConcurrentHandlingStarted()) {                        return;                    }                    this.applyDefaultViewName(processedRequest, err);                    mappedHandler.applyPostHandle(processedRequest, response, err);                } catch (Exception var19) {                    dispatchException = var19;                }                this.processDispatchResult(processedRequest, response, mappedHandler, err, dispatchException);            } catch (Exception var20) {                this.triggerAfterCompletion(processedRequest, response, mappedHandler, var20);            } catch (Error var21) {                this.triggerAfterCompletionWithError(processedRequest, response, mappedHandler, var21);            }        } finally {            if(asyncManager.isConcurrentHandlingStarted()) {                if(mappedHandler != null) {                    mappedHandler.applyAfterConcurrentHandlingStarted(processedRequest, response);                }            } else if(multipartRequestParsed) {                this.cleanupMultipart(processedRequest);            }        }    }

 

    這個方法裡面很多內容不需要關注,需要關注的的我講講

        HttpServletRequest processedRequest = request;        //接收請求        HandlerExecutionChain mappedHandler = null;        //處理器執行鏈        boolean multipartRequestParsed = false;        //多部分請求,檔案上傳        WebAsyncManager asyncManager = WebAsyncUtils.getAsyncManager(request);        //異部請求        try {            try {                               ModelAndView err = null;                 //視圖解析                try {                                        processedRequest = this.checkMultipart(request);                    //檢查是否是多部分請求                    multipartRequestParsed = processedRequest != request;                                        mappedHandler = this.getHandler(processedRequest);                        //這就返回處理器執行鏈

  3.到這兒,點擊getHandler(processedRequest)查看

    protected HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception {        Iterator var2 = this.handlerMappings.iterator();        HandlerExecutionChain handler;        do {            if(!var2.hasNext()) {                return null;            }            HandlerMapping hm = (HandlerMapping)var2.next();            if(this.logger.isTraceEnabled()) {                this.logger.trace("Testing handler map [" + hm + "] in DispatcherServlet with name \‘" + this.getServletName() + "\‘");            }            handler = hm.getHandler(request);        } while(handler == null);        return handler;    }

    我把關鍵代碼提煉出來解釋一波

        //迭代器,沒做泛型,handlerMapping是list集合        Iterator var2 = this.handlerMappings.iterator();        //處理器執行鏈        HandlerExecutionChain handler;        do {            if(!var2.hasNext()) {                return null;            }            //處理器映射器            HandlerMapping hm = (HandlerMapping)var2.next();                       //繼續追蹤            handler = hm.getHandler(request);        } while(handler == null);        return handler;    

  4.追蹤hm.getHandler(request)方法,發現他是HandlerMapping介面的,(Ctrl+H)找它的實作類別AbstractHandlerMapping,ctrl+F找getHandler

    public final HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception {        Object handler = this.getHandlerInternal(request);        if(handler == null) {            handler = this.getDefaultHandler();        }        if(handler == null) {            return null;        } else {            if(handler instanceof String) {                String executionChain = (String)handler;                handler = this.getApplicationContext().getBean(executionChain);            }            HandlerExecutionChain executionChain1 = this.getHandlerExecutionChain(handler, request);            if(CorsUtils.isCorsRequest(request)) {                CorsConfiguration globalConfig = this.corsConfigSource.getCorsConfiguration(request);                CorsConfiguration handlerConfig = this.getCorsConfiguration(handler, request);                CorsConfiguration config = globalConfig != null?globalConfig.combine(handlerConfig):handlerConfig;                executionChain1 = this.getCorsHandlerExecutionChain(request, executionChain1, config);            }            return executionChain1;        }    }

    同樣,我把關鍵代碼提出來解釋一波

    //擷取處理器        Object handler = this.getHandlerInternal(request);        //處理器為空白就用預設的        if(handler == null) {            handler = this.getDefaultHandler();        }        //預設的也是空就返回null        if(handler == null) {            return null;        } else {            //判斷是否是String類型            if(handler instanceof String) {                //這兒就是我們一般用的處理器的從設定檔bean的id                String handlerName = (String)handler;  //  /hello                //這就是Spring啊                handler = this.getApplicationContext().getBean(handlerName);            }
        //擷取處理常式執行鏈
        HandlerExecutionChain executionChain1 = this.getHandlerExecutionChain(handler, request);
    //返回的時候變成攜帶處理器的了 
  
    return this.getHandlerExecutionChain(handler, request); }

  5.追蹤擷取程式執行鏈,this.getHandlerExecutionChain(handler,request)

    protected HandlerExecutionChain getHandlerExecutionChain(Object handler, HttpServletRequest request) {        //三元運算式,是處理器執行鏈就強轉,不是就擷取根據處理器產生一個        HandlerExecutionChain chain = handler instanceof HandlerExecutionChain?(HandlerExecutionChain)handler:new HandlerExecutionChain(handler);        String lookupPath = this.urlPathHelper.getLookupPathForRequest(request);        Iterator var5 = this.adaptedInterceptors.iterator();        while(var5.hasNext()) {            //只需要知道這兒添加攔截器即可            HandlerInterceptor interceptor = (HandlerInterceptor)var5.next();            if(interceptor instanceof MappedInterceptor) {                MappedInterceptor mappedInterceptor = (MappedInterceptor)interceptor;                if(mappedInterceptor.matches(lookupPath, this.pathMatcher)) {                    chain.addInterceptor(mappedInterceptor.getInterceptor());                }            } else {                chain.addInterceptor(interceptor);            }        }        return chain;    }

 

SSM-SpringMVC-04:SpringMVC深入淺出理解HandleMapping(源碼刨析)

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.