springmvc 参数解析绑定原理
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 参数解析绑定原理的更多相关文章
- SpringMVC源码之参数解析绑定原理
摘要 本文从源码层面简单讲解SpringMVC的参数绑定原理 SpringMVC参数绑定相关组件的初始化过程 在理解初始化之前,先来认识一个接口 HandlerMethodArgumentResolv ...
- HandlerMethodReturnValueHandler SpringMVC 参数解析 继承关系以及各解析器解析类型
I HandlerMethodReturnValueHandler (org.springframework.web.method.support) AbstractMessageConverterM ...
- HandlerMethodArgumentResolver SpringMVC 参数解析 继承关系以及各解析器解析类型
HandlerMethodArgumentResolver SpringMVC 参数解析 继承关系以及各解析器解析类型 I HandlerMethodArgumentResolver (org.spr ...
- 一步一步自定义SpringMVC参数解析器
随心所欲,自定义参数解析器绑定数据. 题图:from Zoommy 干货 SpringMVC解析器用于解析request请求参数并绑定数据到Controller的入参上. 自定义一个参数解析器需要实现 ...
- 自定义springmvc参数解析器
实现spring HandlerMethodArgumentResolver接口 通过使用@JsonArg自定义注解来解析json数据(通过fastjson的jsonPath),支持多个参数(@Req ...
- SpringMVC参数自动绑定
SpringMVC的各种参数绑定方式 1. 基本数据类型(以int为例,其他类似):Controller代码: @RequestMapping("saysth.do") publi ...
- 由一个异常开始思考springmvc参数解析
首先记录一下异常,以及异常出现的原因和解决方案 异常主要信息: -- ::, ERROR [.jsp] - Name for argument type [java.lang.String] not ...
- [转载]SpringBoot系列: SpringMVC 参数绑定注解解析
本文转载自 https://www.cnblogs.com/morethink/p/8028664.html, 作者写得非常好, 致谢! SpringMVC 参数绑定注解解析 本文介绍了用于参数绑 ...
- springmvc 请求参数解析细节
springmvc 的请求流程,相信大家已经很熟悉了,不熟悉的同学可以参考下资料! 有了整体流程的概念,是否对其中的实现细节就很清楚呢?我觉得不一定,比如:单是参数解析这块,就是个大学问呢? 首先,我 ...
随机推荐
- python函数的作用域和引用范围
以下内容参考自runoob网站,以总结python函数知识点,巩固基础知识,特此鸣谢! 原文地址:http://www.runoob.com/python3/python3-function.html ...
- Jekyll添加FancyBox 插件
一.简要 这是之前在GitHub Page上面使用博客功能的完善,之前每次传到GitHub上面的图片在博客里面都是显示压缩后的,导致很多代码细节都看不清. Markdown 语法中的图片我们一般是如此 ...
- PHP mysqli_character_set_name() 函数
返回数据库连接的默认字符集: <?php $con=mysqli_connect("localhost","my_user","my_passw ...
- Laravel 5.8: Automatic Policy Resolution
Laravel 5.8: Automatic Policy Resolution March 26, 2019 One of the new features in Laravel 5.8 allow ...
- AtomicInteger如何保证线程安全以及乐观锁/悲观锁的概念
众所周知,JDK提供了AtomicInteger保证对数字的操作是线程安全的,线程安全我首先想到了synchronized和Lock,但是这种方式又有一个名字,叫做互斥锁,一次只能有一个持有锁的线程进 ...
- MySQL 几种性能测试的工具使用
近期由于要比较mysql及其分支mariadb, percona的性能,了解了几个这方面的工具,包括:mysqlslap sysbench tpcc-mysql,做一个整理,备忘,分享 1.mysql ...
- 【luogu1797】faebdc的烦恼-莫队
题目背景 鸟哥(faebdc)自从虐暴NOIP2013以来依然勤奋学习,每天上各种OJ刷题,各种比赛更是不在话下.但这天他遇到了一点小小的麻烦……在一届“Orz鸟哥杯”上,题目是在是太多了!足有n道! ...
- 格符\b的使用示例:每隔1秒消去1个字符
/* 退格符\b的使用示例:每隔1秒消去1个字符 */ #include <time.h> #include <stdio.h> /*--- 等待x毫秒 ---*/ int s ...
- DataTable 转换为List
注意table 列的参数类型,若不为string 需要详细声明 如 typeof(Int32) public static IList<T> Convert ...
- Qt数据库编程_基本
QtSql模块提供了一个平台无关且数据库无关的访问SQL数据库的接口. Qt中的每个数据库连接用一个QSqlDatabase对象来表示:Qt使用不同driver来和各种不同数据库的API进行通讯. Q ...