springmvc 参数解析绑定原理
DispatcherServlet#doDispatch -> ha.handle
RequestMappingHandlerAdapter#handleInternal -> invokeHandlerMethod()->
ServletInvocableHandlerMethod#invokeAndHandle() -> invokeForRequest() ->getMethodArgumentValues()

  1. protected Object[] getMethodArgumentValues(NativeWebRequest request, @Nullable ModelAndViewContainer mavContainer, Object... providedArgs) throws Exception {
  2. //获取当前handler所声明的所有参数,主要包括参数名,参数类型,参数位置,所标注的注解等等属性
  3. MethodParameter[] parameters = this.getMethodParameters();
  4. if (ObjectUtils.isEmpty(parameters)) {
  5. return EMPTY_ARGS;
  6. } else {
  7. Object[] args = new Object[parameters.length];
  8. for(int i = 0; i < parameters.length; ++i) {
  9. MethodParameter parameter = parameters[i];
  10. parameter.initParameterNameDiscovery(this.parameterNameDiscoverer);
  11. // providedArgs是调用方提供的参数,这里主要是判断这些参数中是否有当前类型
  12. // 或其子类型的参数,如果有,则直接使用调用方提供的参数,对于请求处理而言,默认情况下,
  13. // 调用方提供的参数都是长度为0的数组
  14. args[i] = findProvidedArgument(parameter, providedArgs);
  15. if (args[i] == null) {
  16. if (!this.resolvers.supportsParameter(parameter)) {
  17. throw new IllegalStateException(formatArgumentError(parameter, "No suitable resolver"));
  18. }
  19. try {
  20. // 如果能够找到对当前参数进行处理的ArgumentResolver,则调用其
  21. // resolveArgument()方法从request中获取对应的参数值,并且进行转换
  22. args[i] = this.resolvers.resolveArgument(parameter, mavContainer, request, this.dataBinderFactory);
  23. } catch (Exception var10) {
  24. if (this.logger.isDebugEnabled()) {
  25. String exMsg = var10.getMessage();
  26. if (exMsg != null && !exMsg.contains(parameter.getExecutable().toGenericString())) {
  27. this.logger.debug(formatArgumentError(parameter, exMsg));
  28. }
  29. }
  30. throw var10;
  31. }
  32. }
  33. }
  34. return args;
  35. }
  36. }

基础类型的绑定

HandlerMethodArgumentResolver

自定义类型的绑定

ServletModelAttributeMethodProcessor

参数解析绑定总结

  1. SpringMVC初始化时,RequestMappingHandlerAdapter类会把一些默认的参数解析器添加到argumentResolvers中。当SpringMVC接收到请求后首先根据url查找对应的HandlerMethod。
  2. 遍历HandlerMethod的MethodParameter数组
  3. 根据MethodParameter的类型来查找确认使用哪个HandlerMethodArgumentResolver,遍历所有的argumentResolvers的supportsParameter(MethodParameter parameter)方法。。如果返回true,则表示查找成功,当前MethodParameter,使用该HandlerMethodArgumentResolver。这里确认大多都是根据参数的注解已经参数的Type来确认。
  4. 解析参数,从request中解析出MethodParameter对应的参数,这里解析出来的结果都是String类型。
  5. 转换参数,把对应String转换成具体方法所需要的类型,这里就包括了基本类型、对象、List、Set、Map。