SSM-SpringMVC-04:SpringMVC深入浅出理解HandleMapping(源码刨析)
------------吾亦无他,唯手熟尔,谦卑若愚,好学若饥-------------
先从概念理解,从中央调度器,携带参数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; }