参数解析器和返回值解析器

447 阅读2分钟
来到我们最主要的方法:invocableMethod.invokeAndHandle(webRequest, mavContainer);

public void invokeAndHandle(ServletWebRequest webRequest, ModelAndViewContainer mavContainer,
      Object... providedArgs) throws Exception {


//最终执行调用方法获取处理器方法的返回值,内部包含参数解析逻辑
   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;
   }
}

//最终调用处理器方法的逻辑,之前对@ModelAttribute标记方法的执行也是通过这个调用逻辑实现的

public Object invokeForRequest(NativeWebRequest request, @Nullable ModelAndViewContainer mavContainer,
      Object... providedArgs) throws Exception {
//解析处理其方法的所有参数,返回一个参数数组,用于反射调用
   Object[] args = getMethodArgumentValues(request, mavContainer, providedArgs);
   if (logger.isTraceEnabled()) {
      logger.trace("Arguments: " + Arrays.toString(args));
   }

//通过反射执行真实的处理器方法,获得处理器方法执行后的返回值,也就是这里,最终执行了开发者声明@RequestMapping标注的方法
   return doInvoke(args);
}
protected Object[] getMethodArgumentValues(NativeWebRequest request, @Nullable ModelAndViewContainer mavContainer,
      Object... providedArgs) throws Exception {


//获取方法上的参数数组
   MethodParameter[] parameters = getMethodParameters();
   if (ObjectUtils.isEmpty(parameters)) {
      return EMPTY_ARGS;
   }


   Object[] args = new Object[parameters.length];

//遍历这些 参数
   for (int i = 0; i < parameters.length; i++) {
      MethodParameter parameter = parameters[i];

// 初始化参数的参数名获取器,以用来获取参数名
      parameter.initParameterNameDiscovery(this.parameterNameDiscoverer);

//解析通过providedArgs提供的预留参数,当providedArgs中有与当前编辑的参数类型匹配的参数值时,直接使用该值作为最终调用的参数值

//在处理器方法调用时,providedArgs为空,但在异常解析方法与@InitBinder方法调用时,有额外提供的参数
      args[i] = findProvidedArgument(parameter, providedArgs);
      if (args[i] != null) {
         continue;
      }

//否则,尝试判断参数解析器是否支持这种参数,如果支持,则执行解析逻辑
      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 ex) {
         // Leave stack trace for later, exception may actually be resolved and handled...
         if (logger.isDebugEnabled()) {
            String exMsg = ex.getMessage();
            if (exMsg != null && !exMsg.contains(parameter.getExecutable().toGenericString())) {
               logger.debug(formatArgumentError(parameter, exMsg));
            }
         }
         throw ex;
      }
   }
   return args;
}

public Object resolveArgument(MethodParameter parameter, @Nullable ModelAndViewContainer mavContainer,
      NativeWebRequest webRequest, @Nullable WebDataBinderFactory binderFactory) throws Exception {
//执行获取参数解析器逻辑
   HandlerMethodArgumentResolver resolver = getArgumentResolver(parameter);
   if (resolver == null) {
      throw new IllegalArgumentException("Unsupported parameter type [" +
            parameter.getParameterType().getName() + "]. supportsParameter should be called first.");
   }

//使用参数解析器解析参数逻辑
   return resolver.resolveArgument(parameter, mavContainer, webRequest, binderFactory);
}
private HandlerMethodArgumentResolver getArgumentResolver(MethodParameter parameter) {
   HandlerMethodArgumentResolver result = this.argumentResolverCache.get(parameter);
   if (result == null) {
      for (HandlerMethodArgumentResolver resolver : this.argumentResolvers) {
         if (resolver.supportsParameter(parameter)) {
            result = resolver;
            this.argumentResolverCache.put(parameter, result);
            break;
         }
      }
   }
   return result;
}

参数解析过程就完成了,然后调用反射获取返回值;
现在得到了返回值,我们就来看看返回值的解析器:

this.returnValueHandlers.handleReturnValue(
      returnValue, getReturnValueType(returnValue), mavContainer, webRequest);

public void handleReturnValue(@Nullable Object returnValue, MethodParameter returnType,
      ModelAndViewContainer mavContainer, NativeWebRequest webRequest) throws Exception {

   HandlerMethodReturnValueHandler handler = selectHandler(returnValue, returnType);
   if (handler == null) {
      throw new IllegalArgumentException("Unknown return value type: " + returnType.getParameterType().getName());
   }
   handler.handleReturnValue(returnValue, returnType, mavContainer, webRequest);
}
和前面参数解析器的逻辑类似,想必自己也能看得懂;

具体的@RequestPart,@RequestParam,@RequestBody等参数解析,还有@ResponseBody等返回值解析,自己去了解吧;