getHandler(processedRequest);
- 为此请求返回HandlerExecutionChain。按顺序尝试所有的handler mapping
- 获取当前请求对应的处理类,在这个处理链中会包含对应的拦截器的信息。HandlerExecutionChain这个类中包含变和不变量的两部分内容
protected HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception { for (HandlerMapping hm : this.handlerMappings) { HandlerExecutionChain handler = hm.getHandler(request); if (handler != null) { return handler; } } return null; }
循环handlerMappings,然后获取对应的执行链,只要找到一个对应的执行链就返回
SpringMVC默认加载三个请求处理映射类:
RequestMappingHandlerMapping
SimpleUrlHandlerMapping
BeanNameUrlHandlerMapping
这三个类有一个共同的父类:AbstractHandlerMapping。
hm.getHandler(request)这个getHandler方法在AbstractHandlerMapping中,它的子类都没有重写这个方法。
AbstractHandlerMethodMapping#getHandler
@Override public final HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception { // 两个子类重写该方法:AbstractHandlerMethodMapping和AbstractUrlHandlerMapping Object handler = getHandlerInternal(request); // 如果没有找到的话,默认处理类 if (handler == null) { handler = getDefaultHandler(); } // 如果没有默认的处理类,返回null if (handler == null) { return null; } // Bean name or resolved handler? if (handler instanceof String) { String handlerName = (String) handler; handler = getApplicationContext().getBean(handlerName); } // 包装为执行器链 HandlerExecutionChain executionChain = getHandlerExecutionChain(handler, request); // 是不是跨域请求 if (CorsUtils.isCorsRequest(request)) { CorsConfiguration globalConfig = this.corsConfigSource.getCorsConfiguration(request); CorsConfiguration handlerConfig = getCorsConfiguration(handler, request); CorsConfiguration config = (globalConfig != null ? globalConfig.combine(handlerConfig) : handlerConfig); executionChain = getCorsHandlerExecutionChain(request, executionChain, config); } return executionChain; }
AbstractHandlerMethodMapping#getHandlerInternal
@Override protected HandlerMethod getHandlerInternal(HttpServletRequest request) throws Exception { // 得到请求 url 的查询路径 String lookupPath = getUrlPathHelper().getLookupPathForRequest(request); } // 获取并发读锁 this.mappingRegistry.acquireReadLock(); try { // 得到查询路径对应的处理器方法 HandlerMethod handlerMethod = lookupHandlerMethod(lookupPath, request); return (handlerMethod != null ? handlerMethod.createWithResolvedBean() : null); } finally { this.mappingRegistry.releaseReadLock(); } }
getHandlerExecutionChain
创建执行器链的内容:
protected HandlerExecutionChain getHandlerExecutionChain(Object handler, HttpServletRequest request) { //判断handler是不是执行器链,如果不是创建一个执行器链 HandlerExecutionChain chain = (handler instanceof HandlerExecutionChain ? (HandlerExecutionChain) handler : new HandlerExecutionChain(handler)); String lookupPath = this.urlPathHelper.getLookupPathForRequest(request); //包装拦截器 for (HandlerInterceptor interceptor : this.adaptedInterceptors) { if (interceptor instanceof MappedInterceptor) { MappedInterceptor mappedInterceptor = (MappedInterceptor) interceptor; if (mappedInterceptor.matches(lookupPath, this.pathMatcher)) { chain.addInterceptor(mappedInterceptor.getInterceptor()); } } else { chain.addInterceptor(interceptor); } } return chain; }
这个方法主要是创建执行器链,添加拦截器.
判断
if (mappedHandler == null || mappedHandler.getHandler() == null) { noHandlerFound(processedRequest, response); return; }
如果没有找到对应的处理类的话,这里通常会返回404,如果throwExceptionIfNoHandlerFound属性值为true的情况下会抛出异常。
我们继续往下分析:
HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler());
getHandlerAdapter
获取处理适配器
SimpleControllerHandlerAdapter
适配SimpleUrlHandlerMapping和BeanNameUrlHandlerMapping的映射的,也就是实现Controller接口的Handler
AbstractHandlerMethodAdapter
适配RequestMappingHandlerMapping,也就是我们常用的RequestMapping注解
HttpRequestHandlerAdapter
适配远程调用的
SimpleServletHandlerAdapter
适配Servlet实现类的
supports
supportsInternal
总是返回true ,因为任何方法参数和返回值类型会以某种方式加以处理。
不被任何HandlerMethodArgumentResolver识别的方法参数被解释为一个请求参数,如果它是一个简单的类型,或者作为模型属性否则。
没有任何HandlerMethodReturnValueHandler识别的返回值将被解释为一个模型属性
如果是GET请求,内容没有变化则直接返回
applyPreHandle
- 应用已注册的preHandle拦截方法
handle()
mv = ha.handle(processedRequest, response, mappedHandler.getHandler());
执行handle
applyDefaultViewName(processedRequest, mv); mappedHandler.applyPostHandle(processedRequest, response, mv);
如果返回的mv不为null,并且没有设置view,则设置默认的view
应用postHandle拦截器。
processDispatchResult
private void processDispatchResult(HttpServletRequest request, HttpServletResponse response, HandlerExecutionChain mappedHandler, ModelAndView mv, Exception exception) throws Exception { boolean errorView = false; if (exception != null) { if (exception instanceof ModelAndViewDefiningException) { mv = ((ModelAndViewDefiningException) exception).getModelAndView(); } else { Object handler = (mappedHandler != null ? mappedHandler.getHandler() : null); mv = processHandlerException(request, response, handler, exception); errorView = (mv != null); } } //返回的ModelAndView不为null // Did the handler return a view to render? if (mv != null && !mv.wasCleared()) { //解析页面 render(mv, request, response); if (errorView) { WebUtils.clearErrorRequestAttributes(request); } } else { } if (WebAsyncUtils.getAsyncManager(request).isConcurrentHandlingStarted()) { // Concurrent handling started during a forward return; } // 调用处理拦截器的afterCompletion if (mappedHandler != null) { mappedHandler.triggerAfterCompletion(request, response, null); } }
如果
出现异常,返回异常页面
没有异常,ModelAndView不为null,则正常渲染页面,调用拦截器的afterCompletion方法