1. 程式人生 > >SSM-SpringMVC-04:SpringMVC深入淺出理解HandleMapping(源碼刨析)

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

model oba else tro finally asn span ror tor

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

先從概念理解,從中央調度器,攜帶參數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(源碼刨析)