这种废话不多说,我们在doDispatch方法处打上断点
然后以debug模式运行,访问我们之前的delete模式的/user
传的参数分别是请求request跟回复response
HttpServletRequest processedRequest = request; 这一段是用另一个HttpServletRequest 对象processedRequest 接收request HandlerExecutionChain mappedHandler = null; 这是一段处理链 boolean multipartRequestParsed = false; 这是判断是否为文件上传解析器,默认值为false WebAsyncManager asyncManager = WebAsyncUtils.getAsyncManager(request); 这是创建一个异步管理器,用来接收异步请求信息
然后继续往下进行,进入第一层try
ModelAndView mv = null; 这个是创建ModelAndView 对象,初始值为null Object dispatchException = null; 这是创建一个dispatch异常对象,目的是为了以后处理异常
下面进入下一层try
processedRequest = this.checkMultipart(request); 这里是检查我们是不是文件上传 multipartRequestParsed = processedRequest != request; 这里是如果我们是文件上传请求就进行转化
mappedHandler = this.getHandler(processedRequest);
这是重点,根据我们的请求进行判断,寻找合适的处理器,我们点入查看细节
上代码
protected HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception { if (this.handlerMappings != null) { 这里是确定处理器的映射不为空 Iterator var2 = this.handlerMappings.iterator(); 这里是一个遍历器 while(var2.hasNext()) { 只要handlerMappings还有下一个处理器映射就一直执行 HandlerMapping mapping = (HandlerMapping)var2.next(); 将遍历出来的对象转化为HandlerMapping 对象 HandlerExecutionChain handler = mapping.getHandler(request); 调用HandlerMapping 的getHandler对象来获取真正的处理器handler if (handler != null) { 判断如果handler是否为空,非空就返回handler return handler; } } } return null; }
我们通过debug查看这里面HandlerMapping的内容
这里面是我们所有的可调用的Handler,Handler会自动扫描所有带注解的包
我们可以在其中查看扫描到的映射路径
我们作为request请求的请求的应该是对应第一个requestMappingHanlder
所以我们进入了handlerMapping的getHandler
这里如果点击进入
会进入这个页面,因为这是个抽象方法,其实他在AbstractHandlerMapping中重写了
我们通过debug进入
然后接着进入getHandlerInternal
这里我们可以清楚看到映射的方式是delete,路径是/user
我们接着就进入lookupHandlerMethod方法
这里我们可以看到其内部的运行,一个list类型的irectPathMatches通过this.mappingRegistry.getMappingsByDirectPath使用路径/user访问,我们找到了四个/user
而下方的若干个if就是帮助我们确定到底是哪个user的
这里我把源码放在这里
protected HandlerMethod lookupHandlerMethod(String lookupPath, HttpServletRequest request) throws Exception {
List<AbstractHandlerMethodMapping<T>.Match> matches = new ArrayList();
List<T> directPathMatches = this.mappingRegistry.getMappingsByDirectPath(lookupPath);
if (directPathMatches != null) {
this.addMatchingMappings(directPathMatches, matches, request);
}
if (matches.isEmpty()) {
this.addMatchingMappings(this.mappingRegistry.getRegistrations().keySet(), matches, request);
}
if (matches.isEmpty()) {
return this.handleNoMatch(this.mappingRegistry.getRegistrations().keySet(), lookupPath, request);
} else {
AbstractHandlerMethodMapping<T>.Match bestMatch = (AbstractHandlerMethodMapping.Match)matches.get(0);
if (matches.size() > 1) {
Comparator<AbstractHandlerMethodMapping<T>.Match> comparator = new AbstractHandlerMethodMapping.MatchComparator(this.getMappingComparator(request));
matches.sort(comparator);
bestMatch = (AbstractHandlerMethodMapping.Match)matches.get(0);
if (this.logger.isTraceEnabled()) {
this.logger.trace(matches.size() + " matching mappings: " + matches);
}
if (CorsUtils.isPreFlightRequest(request)) {
Iterator var7 = matches.iterator();
while(var7.hasNext()) {
AbstractHandlerMethodMapping<T>.Match match = (AbstractHandlerMethodMapping.Match)var7.next();
if (match.hasCorsConfig()) {
return PREFLIGHT_AMBIGUOUS_MATCH;
}
}
} else {
AbstractHandlerMethodMapping<T>.Match secondBestMatch = (AbstractHandlerMethodMapping.Match)matches.get(1);
if (comparator.compare(bestMatch, secondBestMatch) == 0) {
Method m1 = bestMatch.getHandlerMethod().getMethod();
Method m2 = secondBestMatch.getHandlerMethod().getMethod();
String uri = request.getRequestURI();
throw new IllegalStateException("Ambiguous handler methods mapped for '" + uri + "': {" + m1 + ", " + m2 + "}");
}
}
}
request.setAttribute(BEST_MATCHING_HANDLER_ATTRIBUTE, bestMatch.getHandlerMethod());
this.handleMatch(bestMatch.mapping, lookupPath, request);
return bestMatch.getHandlerMethod();
}
}
后面的代码都是筛选的,意义不大,至此,我们跑通了dispatch