美文网首页Spring MvcSpringFramework程序员
springmvc 参数绑定源码分析

springmvc 参数绑定源码分析

作者: lialzm | 来源:发表于2017-03-20 18:33 被阅读526次

    了解springmvc是如何进行参数绑定的,使用idea对springmvc源码进行逐步调试,源码版本4.3.2

    从@RequestParam注解开始入手,搜索该注解在源码中使用的地方

    Paste_Image.png

    可以看到RequestParam分别在HandlerMethodInvoker,RequestParamMapMethodArgumentResolver,RequestParamMethodArgumentResolver这三个类中进行了实例化
    其中HandlerMethodInvoker是个过期类,已被RequestMappingHandlerAdapter替代
    我们就从RequestMappingHandlerAdapter入手,打开该类的源码,从类名可以看出这是用来处理RequestMapping的,
    在javadoc中可以看到

    An {@link AbstractHandlerMethodAdapter} that supports {@link HandlerMethod}s
    with their method argument and return type signature, as defined via {@code @RequestMapping}
    Support for custom argument and return value types can be added via
    {@link #setCustomArgumentResolvers} and {@link #setCustomReturnValueHandlers}.
    Or alternatively, to re-configure all argument and return value types,
    use {@link #setArgumentResolvers} and {@link #setReturnValueHandlers}

    这里提到了setCustomArgumentResolvers,setCustomReturnValueHandlers方法,即添加自定义参数处理器和自定义返回值处理器

    Paste_Image.png

    我们先进入setCustomArgumentResolvers方法

    Paste_Image.png

    就是个HandlerMethodArgumentResolver集合,然后我们进入HandlerMethodArgumentResolver,这是一个接口,我们可以查看此接口的相关实现

    Paste_Image.png

    进入type hierarchy

    Paste_Image.png

    在这里我们看到了第一步搜索出现的RequestParamMethodArgumentResolver,现在可以基本确定@RequestParam是由此类负责处理
    现在进入RequestParamMethodArgumentResolver类
    该类所有方法

    Paste_Image.png

    supportsParameter是用来判断是否存在RequestParam注解,是则处理,不是则不处理
    resolveName是真正的处理参数的方法
    下面是部分源码

    Paste_Image.png

    可以看到从Request请求中获取参数值并返回
    继续往上搜索,搜索调用resolveName方法的地方

    Paste_Image.png

    进入AbstractNamedValueMethodArgumentResolver的resolveArgument方法
    AbstractNamedValueMethodArgumentResolver是RequestParamMethodArgumentResolver的父类

    Paste_Image.png

    resolveArgument主要处理了RequestParam相关参数,如默认参数,是否必传等
    我们再往上搜索resolveArgument方法的调用方
    HandlerMethodArgumentResolverComposite的resolveArgument方法
    该方法调用了另一个关键方法getArgumentResolver
    即通过参数注解筛选合适的参数处理器
    继续向上搜索resolveArgument方法的调用类

    Paste_Image.png

    进入InvocableHandlerMethod类的getMethodArgumentValues方法
    这个方法里面是对方法所有参数进行遍历获取对应值

    Paste_Image.png

    最后返回了方法所有的参数数组
    继续向上搜索进入InvocableHandlerMethod类的invokeForRequest方法,这是真正调用RequestMapping注解方法的地方

    Paste_Image.png

    doInvoke即使用反射调用方法并获取返回值
    获取返回值后进入ServletInvocableHandlerMethod类的invokeAndHandle对返回值进行处理
    调用HandlerMethodReturnValueHandlerComposite类的handleReturnValue方法
    selectHandler获取合适的返回值处理器
    默认有15个处理器

    Paste_Image.png

    获取到合适处理器后运行该处理器的handleReturnValue方法对参数进行处理
    我使用了@ResponseBody注解,所以进入RequestResponseBodyMethodProcessor类将实体类转换为json

    相关文章

      网友评论

      • 0c87edbbd35e:我的意思指的是如果要自定义参数转化器时是不是重写message-convert这个类就行了,不用重写楼主文章中写的那么多个类
        lialzm:是的
      • 0c87edbbd35e:请问下楼主,在springMVC.xml中配置message-convert这个作用于responsebody和requestBody和楼主这篇文章有关系吗?

      本文标题:springmvc 参数绑定源码分析

      本文链接:https://www.haomeiwen.com/subject/gisinttx.html