SSM-SpringMVC-04:SpringMVC深入淺出理解HandleMapping(源碼刨析)
阿新 • • 發佈:2018-03-21
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(源碼刨析)