-
从HandlerMapping中找到能处理请求的Handler (Controller.method())
-
为当前Handler 找一个适配器 HandlerAdapter,RequestMappingHandlerAdapter
-
HandlerAdapter
0 - 支持方法上标注@RequestMapping 注解的适配器
1 - 支持函数式编程的适配器
....
执行步骤
1、HandlerAdapter
protected HandlerAdapter getHandlerAdapter(Object handler) throws ServletException { if (this.handlerAdapters != null) { for (HandlerAdapter adapter : this.handlerAdapters) { // 是HandlerMethod类型 就选择该适配器 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"); }@Override public final boolean supports(Object handler) { // 判断handler 是否是 HandlerMethod类型 return (handler instanceof HandlerMethod && supportsInternal((HandlerMethod) handler)); }
2、执行目标方法
// Actually invoke the handler. // DispatcherServlet -- doDispatch mv = ha.handle(processedRequest, response, mappedHandler.getHandler());// RequestMappingHandlerAdapter @Override protected ModelAndView handleInternal(HttpServletRequest request, HttpServletResponse response, HandlerMethod handlerMethod) throws Exception { ModelAndView mav; checkRequest(request); // Execute invokeHandlerMethod in synchronized block if required. if (this.synchronizeOnSession) { HttpSession session = request.getSession(false); if (session != null) { Object mutex = WebUtils.getSessionMutex(session); synchronized (mutex) { mav = invokeHandlerMethod(request, response, handlerMethod); } } else { // No HttpSession available -> no mutex necessary mav = invokeHandlerMethod(request, response, handlerMethod); } } else { // No synchronization on session demanded at all... // 执行目标方法 mav = invokeHandlerMethod(request, response, handlerMethod); } if (!response.containsHeader(HEADER_CACHE_CONTROL)) { if (getSessionAttributesHandler(handlerMethod).hasSessionAttributes()) { applyCacheSeconds(response, this.cacheSecondsForSessionAttributeHandlers); } else { prepareResponse(response); } } return mav; }
3、参数解析器
HandlerMethodArgumentResolver
确定将要执行的目标方法的每一个参数值是什么,通过反射
SpringMVC目标方法能写多少种参数类型,取决于参数解析器
// 参数解析器接口 public interface HandlerMethodArgumentResolver { // 判断当前参数是否支持这种解析 -> 支持解析就调用resolveArgument boolean supportsParameter(MethodParameter parameter); @Nullable Object resolveArgument(MethodParameter parameter, @Nullable ModelAndViewContainer mavContainer, NativeWebRequest webRequest, @Nullable WebDataBinderFactory binderFactory) throws Exception; }
4、返回值处理器
// RequestMappingHandlerAdapter类.invokeHandlerMethod // 执行controller的方法 invocableMethod.invokeAndHandle(webRequest, mavContainer);// ServletInvocableHandlerMethod类 public void invokeAndHandle(ServletWebRequest webRequest, ModelAndViewContainer mavContainer, Object... providedArgs) throws Exception { // 执行对应的controller的目标方法 Object returnValue = invokeForRequest(webRequest, mavContainer, providedArgs); setResponseStatus(webRequest); if (returnValue == null) { if (isRequestNotModified(webRequest) || getResponseStatus() != null || mavContainer.isRequestHandled()) { disableContentCachingIfNecessary(webRequest); mavContainer.setRequestHandled(true); return; } } else if (StringUtils.hasText(getResponseStatusReason())) { mavContainer.setRequestHandled(true); return; } mavContainer.setRequestHandled(false); Assert.state(this.returnValueHandlers != null, "No return value handlers"); try { this.returnValueHandlers.handleReturnValue( returnValue, getReturnValueType(returnValue), mavContainer, webRequest); } catch (Exception ex) { if (logger.isTraceEnabled()) { logger.trace(formatErrorForReturnValue(returnValue), ex); } throw ex; } }
5、如何确定方法参数的每一个参数值
// InvocableHandlerMethod protected Object[] getMethodArgumentValues(NativeWebRequest request, @Nullable ModelAndViewContainer mavContainer, Object... providedArgs) throws Exception { // 通过反射,获取方法的参数 MethodParameter[] parameters = this.getMethodParameters(); // 判断是否为空,没有参数列表 if (ObjectUtils.isEmpty(parameters)) { return EMPTY_ARGS; } else { // 不为空 Object[] args = new Object[parameters.length]; for(int i = 0; i < parameters.length; ++i) { MethodParameter parameter = parameters[i]; // 确定参数名 parameter.initParameterNameDiscovery(this.parameterNameDiscoverer); args[i] = findProvidedArgument(parameter, providedArgs); if (args[i] == null) { // 判断26个解析器中是否有支持当前参数类型的解析器 if (!this.resolvers.supportsParameter(parameter)) { throw new IllegalStateException(formatArgumentError(parameter, "No suitable resolver")); } try { // 获取当前参数的值 args[i] = this.resolvers.resolveArgument(parameter, mavContainer, request, this.dataBinderFactory); } catch (Exception var10) { if (logger.isDebugEnabled()) { String exMsg = var10.getMessage(); if (exMsg != null && !exMsg.contains(parameter.getExecutable().toGenericString())) { logger.debug(formatArgumentError(parameter, exMsg)); } } throw var10; } } } return args; } }
逐个判断26个参数解析器哪个支持解析当前参数
@Nullable private HandlerMethodArgumentResolver getArgumentResolver(MethodParameter parameter) { HandlerMethodArgumentResolver result = (HandlerMethodArgumentResolver)this.argumentResolverCache.get(parameter); if (result == null) { Iterator var3 = this.argumentResolvers.iterator(); while(var3.hasNext()) { HandlerMethodArgumentResolver resolver = (HandlerMethodArgumentResolver)var3.next(); if (resolver.supportsParameter(parameter)) { result = resolver; this.argumentResolverCache.put(parameter, resolver); break; } } } return result; }
最后,通过参数解析器给当前参数赋值