handlerMethodArgumentResolver:方法参数解析器接口,这个接口是springmvc参数解析绑定的核心接口。不同的参数类型绑定都是通过实行这个接口来实现。也可以通过实现这个接口来自定义参数解析器。这个接口有如下两个方法:

public interface HandlerMethodArgumentResolver{

   //该解析器是否支持parameter参数的解析
boolean supportsParameter (MethodParameter parameter); //将方法参数从给定请求(webRequest)解析为参数值并返回
Object resolveArgument(MethodParameter parameter,
ModelAndViewContainer mavContainer,
NativeWebRequest webRequest,
WebDataBinderFactory binderFactory) throws Exceptions; }

初始化

RequestMappingHandlerAdapter.java类的afterProperitesSet方法初始化相关方法参数解析器,代码如下:

public void afterPropertiesSet(){
if(this.argumentResolvers==null){
//初始化springmvc默认的方法参数解析器,并添加到argumentResolvers(HandlerMethodArgumentResolverComposite)
List<HandlerMethodArgumentResolver> resolvers = getDefaultArgumentResolvers():
this.argumentResolvers = new HandlerMethodArgumentResolverComposite().addResolvers(resolvers); }
if(this.initBinderArgumentResolvers==null){
//初始化springmvc默认的初始化绑定器(@InitBinder)参数解析器,并添加至initBinderArgumentResolvers(HandlerMethosArgumentResolverComposite)
List<HandlerMethosArgumentResolver> resolvers = getDefaultInitBinderArgumentResolvers();
this.initBinderArgumentResolvers = new HandlerMethodArgumentResolverComposite().addResolvers(resolvers);
}
if(this.returnValueHandlers==null){
//获取默认的方法返回值解析器
List<HandlerMethodreturnValueHandler> handler = getDefaultReturnValueHandlers();
this.returnValueHandlers = new HandlerMethodReturnValueHandlerComposite().addHandlers(handlers);
}
initControllerAdviceCache();
}

现在我们进入getDefaultArgumentResolvers方法,代码如下

//默认的参数解析,创建了默认的24个参数解析器,并添加至resolvers
//这里的24个参数解析器都是针对不同的参数类型来解析的
private List<HandlerMethodArgumentResolver> getDefaultArgumentResolvers() {
List<HandlerMethodArgumentResolver> resolvers = new ArrayList<HandlerMethodArgumentResolver>(); // 基于注解的参数解析器 //一般用于带有@RequestParam注解的简单参数绑定,简单参数比如byte、int、long、double、String以及对应的包装类型
resolvers.add(new RequestParamMethodArgumentResolver(getBeanFactory(), false));
//用于处理带有@RequestParam注解,且参数类型为Map的解析绑定
resolvers.add(new RequestParamMapMethodArgumentResolver());
//一般用于处理带有@PathVariable注解的默认参数绑定
resolvers.add(new PathVariableMethodArgumentResolver());
//也是用于带有@PathVariable注解的Map相关参数绑定,后续还有一些默认的参数解析器。后续还有一些参数解析器,我这里都不一一解释了。想具体确认某个参数会交个哪个参数解析器处理,可以通过以下解析器的supportsParameter(MethodParameter parameter)方法得知
resolvers.add(new PathVariableMapMethodArgumentResolver());
resolvers.add(new MatrixVariableMethodArgumentResolver());
resolvers.add(new MatrixVariableMapMethodArgumentResolver());
resolvers.add(new ServletModelAttributeMethodProcessor(false));
resolvers.add(new RequestResponseBodyMethodProcessor(getMessageConverters()));
resolvers.add(new RequestPartMethodArgumentResolver(getMessageConverters()));
resolvers.add(new RequestHeaderMethodArgumentResolver(getBeanFactory()));
resolvers.add(new RequestHeaderMapMethodArgumentResolver());
resolvers.add(new ServletCookieValueMethodArgumentResolver(getBeanFactory()));
resolvers.add(new ExpressionValueMethodArgumentResolver(getBeanFactory())); // 基于类型的参数解析器
resolvers.add(new ServletRequestMethodArgumentResolver());
resolvers.add(new ServletResponseMethodArgumentResolver());
resolvers.add(new HttpEntityMethodProcessor(getMessageConverters()));
resolvers.add(new RedirectAttributesMethodArgumentResolver());
resolvers.add(new ModelMethodProcessor());
resolvers.add(new MapMethodProcessor());
resolvers.add(new ErrorsMethodArgumentResolver());
resolvers.add(new SessionStatusMethodArgumentResolver());
resolvers.add(new UriComponentsBuilderMethodArgumentResolver()); // Custom arguments
if (getCustomArgumentResolvers() != null) {
resolvers.addAll(getCustomArgumentResolvers());
}

参数解析器添加至HandlerMethodArgumentResolverComposite这个类,它是实现了HandlerMethodArgumentResolver接口。这里运用设计模式的中的composite模式(组合模式),在springmvc中,所有请求的参数解析都是进入HandlerMethodArgumentResolverComposite类来实现的。它有两个成员变量,如下

//它的元素在RequestMappingHandlerAdapter类的afterPropertiesSet方法中被添加,存放的是springmvc默认的一些HandlerMethodArgumentResolver参数解析器
private final List<HandlerMethodArgumentResolver> argumentResolvers = new LinkedList<HandlerMethodArgument>Resolver();
//存放已经解析过的参数,已经对应的HandlerMethodAgrumentResolver解析器,加快查找过程
private final Map<MethodParameter,HandlerMethodArgumentResolver> argumentResolverCache = new ConcurrentHashMap<MethodParameter,HandlerMethodArgumentResolver>(256);

参考资料:https://www.cnblogs.com/w-y-c-m/p/8443892.html

springmvc 参数解析绑定原理的更多相关文章

  1. SpringMVC源码之参数解析绑定原理

    摘要 本文从源码层面简单讲解SpringMVC的参数绑定原理 SpringMVC参数绑定相关组件的初始化过程 在理解初始化之前,先来认识一个接口 HandlerMethodArgumentResolv ...

  2. HandlerMethodReturnValueHandler SpringMVC 参数解析 继承关系以及各解析器解析类型

    I HandlerMethodReturnValueHandler (org.springframework.web.method.support) AbstractMessageConverterM ...

  3. HandlerMethodArgumentResolver SpringMVC 参数解析 继承关系以及各解析器解析类型

    HandlerMethodArgumentResolver SpringMVC 参数解析 继承关系以及各解析器解析类型 I HandlerMethodArgumentResolver (org.spr ...

  4. 一步一步自定义SpringMVC参数解析器

    随心所欲,自定义参数解析器绑定数据. 题图:from Zoommy 干货 SpringMVC解析器用于解析request请求参数并绑定数据到Controller的入参上. 自定义一个参数解析器需要实现 ...

  5. 自定义springmvc参数解析器

    实现spring HandlerMethodArgumentResolver接口 通过使用@JsonArg自定义注解来解析json数据(通过fastjson的jsonPath),支持多个参数(@Req ...

  6. SpringMVC参数自动绑定

    SpringMVC的各种参数绑定方式 1. 基本数据类型(以int为例,其他类似):Controller代码: @RequestMapping("saysth.do") publi ...

  7. 由一个异常开始思考springmvc参数解析

    首先记录一下异常,以及异常出现的原因和解决方案 异常主要信息: -- ::, ERROR [.jsp] - Name for argument type [java.lang.String] not ...

  8. [转载]SpringBoot系列: SpringMVC 参数绑定注解解析

    本文转载自 https://www.cnblogs.com/morethink/p/8028664.html, 作者写得非常好, 致谢! SpringMVC 参数绑定注解解析   本文介绍了用于参数绑 ...

  9. springmvc 请求参数解析细节

    springmvc 的请求流程,相信大家已经很熟悉了,不熟悉的同学可以参考下资料! 有了整体流程的概念,是否对其中的实现细节就很清楚呢?我觉得不一定,比如:单是参数解析这块,就是个大学问呢? 首先,我 ...

随机推荐

  1. Ubuntu 搭建 Ftp 服务器

    1.在 ubuntu 中 下载 vsftpd  要是你安装了 vsftpd  输入:vsftpd -v ,会有版本提示 如果没有,则进行安装 vsftpd 输入  apt-get install vs ...

  2. 使用@ConfigurationProperties注解 提示 “Spring Boot Configuration Annotation Processor not found in classpath ”

    解决方案: 在 pom.xml 添加依赖 <dependency> <groupId>org.springframework.boot</groupId> < ...

  3. Entity Framework学习过程

    ///安装ef nuget中文控制台指令 PM> Install-Package EntityFramework.zh-Hans <!--配置数据库连接--> <connect ...

  4. codeforces 1249 D2 Too Many Segments (hard version) 贪心+树状数组

    题意 给定n个线段,线段可以相交,第\(i\)个线段覆盖的区间为\([l_i,r_i]\),问最少删除多少个线段让覆盖每个点的线段数量小于等于k. 分析 从左往右扫每个点\(x\),若覆盖点\(x\) ...

  5. 前端逼死强迫症系列之Html

    概述 HTML是英文Hyper Text Mark-up Language(超文本标记语言)的缩写,他是一种制作万维网页面标准语言(标记).相当于定义统一的一套规则,大家都来遵守他,这样就可以让浏览器 ...

  6. Solr 7.X 安装和配置--Linux篇

    1. 关闭防火墙和Selinux 2. 安装所需环境JDK 3. 下载Solr7.4版本 4. 下载并配置solr的中文分词器IK Analyzer 5. 启动Solr 6. 注意事项以及说明 1. ...

  7. HDU 1114 Piggy-Bank ——(完全背包)

    差不多是一个裸的完全背包,只是要求满容量的最小值而已.那么dp值全部初始化为inf,并且初始化一下dp[0]即可.代码如下: #include <stdio.h> #include < ...

  8. Reids入门介绍

    一.入门概述 1.是什么? Redis:REmote DIctionary Server(远程字典服务器) 是完全开源免费的,用C语言编写的,遵守BSD协议,是一个高性能的(key/value)分布式 ...

  9. golang中文件以及文件夹路径相关操作

    获取目录中所有文件使用包: io/ioutil 使用方法: ioutil.ReadDir 读取目录 dirmane 中的所有目录和文件(不包括子目录) 返回读取到的文件的信息列表和读取过程中遇到的任何 ...

  10. 2019balsn两道web和2019巅峰极客一道web记录

    遇到3道有点意思的web,记录一下~ web1 题目地址:http://warmup.balsnctf.com/ 源码如下所示: <?php if (($secret = base64_deco ...