SpringMVC源码阅读RequestMappingHandlerAdapter如何处理Handle(八)
接口
public interface HandlerAdapter { /** * 是否能处理指定Handler * @param var1 * @return */ boolean supports(Object var1); /** * 处理Handler * @param var1 * @param var2 * @param var3 * @return * @throws Exception */ @Nullable ModelAndView handle(HttpServletRequest var1, HttpServletResponse var2, Object var3) throws Exception; /** * 获取资源最后一次更新时间 * @param var1 * @param var2 * @return */ long getLastModified(HttpServletRequest var1, Object var2); }
类图
我们回到Dispatcher开始看起
DispatcherServlet
doDispatch
org.springframework.web.servlet.FrameworkServlet#service
->
org.springframework.web.servlet.FrameworkServlet#processRequest
->
org.springframework.web.servlet.DispatcherServlet#doService
->
org.springframework.web.servlet.DispatcherServlet#doDispatch
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 mv = null; Exception dispatchException = null; try { /** * 如果配置了MultipartResolver 会调用 isMultipart() 方法判断请求中是否包含文件。 * 如果请求数据中包含文件,则调用 MultipartResolver 的 resolveMultipart() * 方法对请求的数据进行解析,然后将文件数据解析成 MultipartFile * 并封装在 MultipartHttpServletRequest (继承了 HttpServletRequest) 对象中并返回 */ processedRequest = this.checkMultipart(request); //是否被解析 multipartRequestParsed = processedRequest != request; //通过HandlerMapping获得 HandlerExecutionChanin如:org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping //org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMappin mappedHandler = this.getHandler(processedRequest); if (mappedHandler == null || mappedHandler.getHandler() == null) { //没获取到抛出404异常 this.noHandlerFound(processedRequest, response); return; } //<1>返回对应能处理的HandlerAdapter HandlerAdapter ha = this.getHandlerAdapter(mappedHandler.getHandler()); String method = request.getMethod(); boolean isGet = "GET".equals(method); if (isGet || "HEAD".equals(method)) { long lastModified = ha.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; } //<3>真正的处理方法 返回视图 没有视图则返回null mv = ha.handle(processedRequest, response, mappedHandler.getHandler()); //是否开启异步管理器 if (asyncManager.isConcurrentHandlingStarted()) { return; } //设置默认的viewName this.applyDefaultViewName(processedRequest, mv); //后置处理 拦截器 mappedHandler.applyPostHandle(processedRequest, response, mv); } catch (Exception var19) { dispatchException = var19; } //处理正常和异常的请求调用结果。 this.processDispatchResult(processedRequest, response, mappedHandler, mv, dispatchException); } catch (Exception var20) { //触发异常拦截器的AfterCompletion实现 this.triggerAfterCompletion(processedRequest, response, mappedHandler, var20); } catch (Error var21) { //触发异常拦截器的AfterCompletion实现 this.triggerAfterCompletionWithError(processedRequest, response, mappedHandler, var21); } } finally { if (asyncManager.isConcurrentHandlingStarted()) { if (mappedHandler != null) { mappedHandler.applyAfterConcurrentHandlingStarted(processedRequest, response); } } else if (multipartRequestParsed) { this.cleanupMultipart(processedRequest); } } }
<1>getHandlerAdapter
org.springframework.web.servlet.FrameworkServlet#service
->
org.springframework.web.servlet.FrameworkServlet#processRequest
->
org.springframework.web.servlet.DispatcherServlet#doService
->
org.springframework.web.servlet.DispatcherServlet#doDispatch
->
org.springframework.web.servlet.DispatcherServlet#getHandlerAdapter
protected HandlerAdapter getHandlerAdapter(Object handler) throws ServletException { if (this.handlerAdapters != null) { Iterator var2 = this.handlerAdapters.iterator(); while(var2.hasNext()) { HandlerAdapter adapter = (HandlerAdapter)var2.next(); //<2>遍历所有适配器 传入handler 判断判断adapter是否能处理 if (adapter.supports(handler)) { return adapter; } } } throw new ServletException("No adapter for handler [" + handler + "]: The DispatcherServlet configuration needs to include a HandlerAdapter that supports this handler"); }
RequestMappingHandlerAdapter
<2>supports
org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter#supports
public final boolean supports(Object handler) { //判断Handler是否是HandlerMethod 类型 supportsInternal是个抽象方法由子类实现 也就是RequestMappingHandlerAdapter return handler instanceof HandlerMethod && this.supportsInternal((HandlerMethod)handler); }
org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter#supports
->
org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter#supportsInternal
protected boolean supportsInternal(HandlerMethod handlerMethod) { return true; }
<3>handle
org.springframework.web.servlet.FrameworkServlet#service
->
org.springframework.web.servlet.FrameworkServlet#processRequest
->
org.springframework.web.servlet.DispatcherServlet#doService
->
org.springframework.web.servlet.DispatcherServlet#doDispatch
->
org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter#handle
public final ModelAndView handle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { //<4>调用子类的实现 抽象方法模板方法实现 return this.handleInternal(request, response, (HandlerMethod)handler); }
<4>handleInternal
org.springframework.web.servlet.FrameworkServlet#service
->
org.springframework.web.servlet.FrameworkServlet#processRequest
->
org.springframework.web.servlet.DispatcherServlet#doService
->
org.springframework.web.servlet.DispatcherServlet#doDispatch
->
org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter#handle
->
org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter#handleInternal
protected ModelAndView handleInternal(HttpServletRequest request, HttpServletResponse response, HandlerMethod handlerMethod) throws Exception { //<5>检查是否配置了只能处理请求 以及是否必须存在session而没有传 this.checkRequest(request); ModelAndView mav; //是否有配置根据session加锁 if (this.synchronizeOnSession) { //true为如果不存在session则创建一个并返回 false不存在直接返回null HttpSession session = request.getSession(false); if (session != null) { /** * Object mutex = session.getAttribute(SESSION_MUTEX_ATTRIBUTE); * 如果为空则返回当前session对象 当我们有需求保证一个session原子性的时候用吧 就一个加同步锁动作 */ Object mutex = WebUtils.getSessionMutex(session); synchronized(mutex) { //<6>执行处理返回modelView mav = this.invokeHandlerMethod(request, response, handlerMethod); } } else { //<6>执行处理返回modelView mav = this.invokeHandlerMethod(request, response, handlerMethod); } } else { //<6>执行处理求返回modelView mav = this.invokeHandlerMethod(request, response, handlerMethod); } /** * 响应头Cache-Control是通知浏览器缓存 * 这里主要是@SessionAttribute用法的处理 * 很少用到 也可兼容https://blog.csdn.net/qq_38737992/article/details/89763067 处理 */ if (!response.containsHeader("Cache-Control")) { if (this.getSessionAttributesHandler(handlerMethod).hasSessionAttributes()) { this.applyCacheSeconds(response, this.cacheSecondsForSessionAttributeHandlers); } else { this.prepareResponse(response); } } return mav; }
<5>checkRequest
org.springframework.web.servlet.FrameworkServlet#service
->
org.springframework.web.servlet.FrameworkServlet#processRequest
->
org.springframework.web.servlet.DispatcherServlet#doService
->
org.springframework.web.servlet.DispatcherServlet#doDispatch
->
org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter#handle
->
org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter#handleInternal
->
org.springframework.web.servlet.support.WebContentGenerator#checkRequest
protected final void checkRequest(HttpServletRequest request) throws ServletException { //获得请求方式 String method = request.getMethod(); //判断是否支持 我们可以通过这个支持的请求方式 if (this.supportedMethods != null && !this.supportedMethods.contains(method)) { throw new HttpRequestMethodNotSupportedException(method, this.supportedMethods); //判断是否配置了必须存在session } else if (this.requireSession && request.getSession(false) == null) { throw new HttpSessionRequiredException("Pre-existing session required but none found"); } }
<6>invokeHandlerMethod
org.springframework.web.servlet.FrameworkServlet#service
->
org.springframework.web.servlet.FrameworkServlet#processRequest
->
org.springframework.web.servlet.DispatcherServlet#doService
->
org.springframework.web.servlet.DispatcherServlet#doDispatch
->
org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter#handle
->
org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter#handleInternal
->
org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter#invokeHandlerMethod
protected ModelAndView invokeHandlerMethod(HttpServletRequest request, HttpServletResponse response, HandlerMethod handlerMethod) throws Exception { ServletWebRequest webRequest = new ServletWebRequest(request, response); ModelAndView var15; try { WebDataBinderFactory binderFactory = this.getDataBinderFactory(handlerMethod); ModelFactory modelFactory = this.getModelFactory(handlerMethod, binderFactory); //交给ServletInvocableHandlerMethod 对象代理handlerMethod ServletInvocableHandlerMethod invocableMethod = this.createInvocableHandlerMethod(handlerMethod); //入参绑定器 set 后续使用 if (this.argumentResolvers != null) { invocableMethod.setHandlerMethodArgumentResolvers(this.argumentResolvers); } //返回值绑定器 if (this.returnValueHandlers != null) { invocableMethod.setHandlerMethodReturnValueHandlers(this.returnValueHandlers); } invocableMethod.setDataBinderFactory(binderFactory); invocableMethod.setParameterNameDiscoverer(this.parameterNameDiscoverer); ModelAndViewContainer mavContainer = new ModelAndViewContainer(); mavContainer.addAllAttributes(RequestContextUtils.getInputFlashMap(request)); modelFactory.initModel(webRequest, mavContainer, invocableMethod); mavContainer.setIgnoreDefaultModelOnRedirect(this.ignoreDefaultModelOnRedirect); AsyncWebRequest asyncWebRequest = WebAsyncUtils.createAsyncWebRequest(request, response); //异步超时时间 asyncWebRequest.setTimeout(this.asyncRequestTimeout); WebAsyncManager asyncManager = WebAsyncUtils.getAsyncManager(request); //设置线程池 asyncManager.setTaskExecutor(this.taskExecutor); asyncManager.setAsyncWebRequest(asyncWebRequest); //拦截器 asyncManager.registerCallableInterceptors(this.callableInterceptors); //DeferredResult方式拦截器 asyncManager.registerDeferredResultInterceptors(this.deferredResultInterceptors); Object result; /** * 主要针对我们返回值是Callable 会释放Dispatcher占用的线程 交给的taskExecutor之心你那个 但是与客户端连接还保持 * 当拿回结果 从新走Dispatcher入口进来 这里判断就会是true */ if (asyncManager.hasConcurrentResult()) { result = asyncManager.getConcurrentResult(); mavContainer = (ModelAndViewContainer)asyncManager.getConcurrentResultContext()[0]; asyncManager.clearConcurrentResult(); LogFormatUtils.traceDebug(this.logger, (traceOn) -> { String formatted = LogFormatUtils.formatValue(result, !traceOn); return "Resume with async result [" + formatted + "]"; }); //同时这类替换invocableMethod为ServletInvocableHandlerMethod.ConcurrentResultHandlerMethod 继承ServletInvocableHandlerMethod invocableMethod = invocableMethod.wrapConcurrentResult(result); } //<7>执行后续请求处理 invocableMethod.invokeAndHandle(webRequest, mavContainer, new Object[0]); if (asyncManager.isConcurrentHandlingStarted()) { result = null; return (ModelAndView)result; } //<如果我们返回ModelAndView则会被ModelAndViewMethodReturnValueHandler 封装到 mavContainenr 这里则根据MavContainer获取 var15 = this.getModelAndView(mavContainer, modelFactory, webRequest); } finally { webRequest.requestCompleted(); } return var15; }
ServletInvocableHandlerMethod
<7>invokeAndHandle
org.springframework.web.servlet.FrameworkServlet#service
->
org.springframework.web.servlet.FrameworkServlet#processRequest
->
org.springframework.web.servlet.DispatcherServlet#doService
->
org.springframework.web.servlet.DispatcherServlet#doDispatch
->
org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter#handle
->
org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter#handleInternal
->
org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter#invokeHandlerMethod
->
org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod#invokeAndHandle
public void invokeAndHandle(ServletWebRequest webRequest, ModelAndViewContainer mavContainer, Object... providedArgs) throws Exception { //<7_1>执行参数绑定 执行控制器方法取回返回结果 Object returnValue = this.invokeForRequest(webRequest, mavContainer, providedArgs); this.setResponseStatus(webRequest); if (returnValue == null) { if (this.isRequestNotModified(webRequest) || this.getResponseStatus() != null || mavContainer.isRequestHandled()) { mavContainer.setRequestHandled(true); return; } } else if (StringUtils.hasText(this.getResponseStatusReason())) { mavContainer.setRequestHandled(true); return; } mavContainer.setRequestHandled(false); //必须返回值处理器 Assert.state(this.returnValueHandlers != null, "No return value handlers"); try { //<10>通过返回值处理器进行返回值处理 this.returnValueHandlers.handleReturnValue(returnValue, this.getReturnValueType(returnValue), mavContainer, webRequest); } catch (Exception var6) { if (this.logger.isTraceEnabled()) { this.logger.trace(this.formatErrorForReturnValue(returnValue), var6); } throw var6; } }
<7_1>invokeForRequest
org.springframework.web.servlet.FrameworkServlet#service
->
org.springframework.web.servlet.FrameworkServlet#processRequest
->
org.springframework.web.servlet.DispatcherServlet#doService
->
org.springframework.web.servlet.DispatcherServlet#doDispatch
->
org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter#handle
->
org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter#handleInternal
->
org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter#invokeHandlerMethod
->
org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod#invokeAndHandle
->
org.springframework.web.method.support.InvocableHandlerMethod#invokeForRequest
public Object invokeForRequest(NativeWebRequest request, @Nullable ModelAndViewContainer mavContainer, Object... providedArgs) throws Exception { //<8>通过绑定器绑定参数 Object[] args = this.getMethodArgumentValues(request, mavContainer, providedArgs); if (this.logger.isTraceEnabled()) { this.logger.trace("Arguments: " + Arrays.toString(args)); } //<9>调用对应的controller方法 return this.doInvoke(args); }
<8>getMethodArgumentValues
org.springframework.web.method.support.InvocableHandlerMethod#getMethodArgumentValues
protected Object[] getMethodArgumentValues(NativeWebRequest request, @Nullable ModelAndViewContainer mavContainer, Object... providedArgs) throws Exception { //获得对应的绑定参数 MethodParameter[] parameters = this.getMethodParameters(); Object[] args = new Object[parameters.length]; for(int i = 0; i < parameters.length; ++i) { MethodParameter parameter = parameters[i]; parameter.initParameterNameDiscovery(this.parameterNameDiscoverer); //这里是优先获取 @Init方法注册的合适的绑定器 返回的类型绑定器 args[i] = this.resolveProvidedArgument(parameter, providedArgs); if (args[i] == null) { //遍历所有参数绑定器找到合适的绑定器 if (this.argumentResolvers.supportsParameter(parameter)) { try { //解析出参数 args[i] = this.argumentResolvers.resolveArgument(parameter, mavContainer, request, this.dataBinderFactory); } catch (Exception var10) { if (this.logger.isDebugEnabled()) { String message = var10.getMessage(); if (message != null && !message.contains(parameter.getExecutable().toGenericString())) { this.logger.debug(formatArgumentError(parameter, message)); } } throw var10; } } else if (args[i] == null) { throw new IllegalStateException(formatArgumentError(parameter, "No suitable resolver")); } } } //返回参数 return args; }
<9>doInvoke
org.springframework.web.method.support.InvocableHandlerMethod#doInvoke
protected Object doInvoke(Object... args) throws Exception { ReflectionUtils.makeAccessible(this.getBridgedMethod()); try { //反射调用对应的Method方法 return this.getBridgedMethod().invoke(this.getBean(), args); } catch (IllegalArgumentException var4) { this.assertTargetBean(this.getBridgedMethod(), this.getBean(), args); String text = var4.getMessage() != null ? var4.getMessage() : "Illegal argument"; throw new IllegalStateException(this.formatInvokeError(text, args), var4); } catch (InvocationTargetException var5) { Throwable targetException = var5.getTargetException(); if (targetException instanceof RuntimeException) { throw (RuntimeException)targetException; } else if (targetException instanceof Error) { throw (Error)targetException; } else if (targetException instanceof Exception) { throw (Exception)targetException; } else { throw new IllegalStateException(this.formatInvokeError("Invocation failure", args), targetException); } } }
<10>handleReturnValue
org.springframework.web.method.support.InvocableHandlerMethod#handleReturnValue
public void handleReturnValue(@Nullable Object returnValue, MethodParameter returnType, ModelAndViewContainer mavContainer, NativeWebRequest webRequest) throws Exception { //<11>根据响应值和响应参数选取合适的BindType HandlerMethodReturnValueHandler handler = this.selectHandler(returnValue, returnType); if (handler == null) { throw new IllegalArgumentException("Unknown return value type: " + returnType.getParameterType().getName()); } else { //写入body 我们可以自定义绑定在写入之前执行一些逻辑 handler.handleReturnValue(returnValue, returnType, mavContainer, webRequest); } }
<11>selectHandler
org.springframework.web.method.support.InvocableHandlerMethod#selectHandler
@Nullable private HandlerMethodReturnValueHandler selectHandler(@Nullable Object value, MethodParameter returnType) { boolean isAsyncValue = this.isAsyncReturnValue(value, returnType); Iterator var4 = this.returnValueHandlers.iterator(); HandlerMethodReturnValueHandler handler; do { do { if (!var4.hasNext()) { return null; } handler = (HandlerMethodReturnValueHandler)var4.next(); } while(isAsyncValue && !(handler instanceof AsyncHandlerMethodReturnValueHandler)); //返回supportsReturnType 调用判断是否能处理 } while(!handler.supportsReturnType(returnType)); return handler; }
如:RequestBody绑定器的实现
public boolean supportsReturnType(MethodParameter returnType) { return AnnotatedElementUtils.hasAnnotation(returnType.getContainingClass(), ResponseBody.class) || returnType.hasMethodAnnotation(ResponseBody.class); }
总结
1.RequestMappingHandlerAdapter最终内部会将请求委托给ServletInvocableHandlerMethod处理
2.ServletInvocableHandlerMethod 会先经过参数绑定器获得参数args数组
3.然后通能反射调用Controller的对应方法
4.再通过响应绑定器对不同的响应内容做处理 比如解析@ResponseBody的响应处理器