Spring3.1.0实现原理分析(十六).MVC数据绑定器

       大家好,今天我们分析下数据绑定器(DataBinder),DataBinder是用来干嘛的呢?是用来给bean属性赋值的,并且还提供了校验bean属性值的功能。分析它的实现原理会涉及到多个spring模块的功能,具体有“属性访问器”、“验证器”、“类型转换”、“国际化”。 这些模块我都写过专门的博客对它们进行分析(大家可以找下)。如果说上述各模块是左勾拳或右勾拳的话,那么DataBinder就是一套组合拳,因为DataBinder就是对其它模块的综合运用。

       我用一张图来表现下这种关系。

      


下面是一张简化的数据绑定器模块类结构图,我们对照着图进行分析。

   


一. DataBinder解析

1. DataBinder

       DataBinder类实现了两个最核心的功能,分别是执行验证和执行绑定。执行验证就是委托给spring验证器模块完成的,具体可以看这篇博客《MVC验证器模块》。那么执行绑定,也就是给bean属性赋值的功能是由谁来完成的呢?答案是:BeanPropertyBindingResult。

       BeanPropertyBindingResult这个类在我之前的博客中从未出现过,这个是个什么东西呢,简单的说它是BeanWrapper和FieldError容器的合体,它不仅具备存取bean属性值的功能还拥有管理验证失败消息的功能,这里的管理主要是指注册FieldError,获取FieldError,BeanPropertyBindingResult之所以具备这个功能是因为它实现Errors接口。验证器对目标对象执行验证后能获取到jsr303规范的验证失败结果对象,然后spring验证器会把验证失败结果对象转换成自己的FieldError对象(之前也说过FieldError本质是封装了解析一个国际化消息所需要的信息),并把FieldError对象置入BeanPropertyBindingResult。

       我用张图片表现下这个过程。

       

2. WebDataBinder

       WebDataBinder是DataBinder的派生类,这个负责实现的功能就简单多了,它负责对mpvs中的PropertyValue进行整理。之前的博客里也说过,凡是要被赋值给bean属性的值,都会先被包装成PropertyValue对象,它包含两个信息,第一当然是值喽,其次是bean属性访问表达式,说白了就是SPEL。mpvs可以理解为PropertyValue的集合。             WebDataBinder会遍历所有的PropertyValue,发现属性名称是以“!”或“_”开头的,则把“!”和"_”去掉。至于为什么要这么处理,估计就是跟view有关,后头再解。

3. ServletRequestDataBinder 和 ExtendedServletRequestDataBinder

       把这两个派生类放在一块讲,是因为它们负责实现的功能是类似的,就是获取mpvs。上头说了,如果想给bean属性赋值,首先得有mpvs,那么mpvs是从哪来的呢?来自于request请求对象。

       ServletRequestDataBinder: 把request请求对象的请求参数集转换成mpvs;如果是文件上传请求对象,则把上传的文件对象置入mpvs。

       ExtendedServletRequestDataBinder:把存储在request属性集中的uri模板变量添加到mpvs。


二. WebBindingInitializer解析

这个接口用来初始化DataBinder,接口中只定义了一个方法,方法的第二个参数目前是没用处的。

void initBinder(WebDataBinder binder, WebRequest request);
WebBindingInitializer接口有个默认的实现类ConfigurableWebBindingInitializer,用户通过修改ConfigurableWebBindingInitialize属性值从而影响DataBinder属性值。可以通过如下的方式设置ConfigurableWebBindingInitialize属性值。

<mvc:annotation-driven conversion-service="conversionService" validator="validator" message-codes-resolver="messageCodesResolver" />

<bean id="conversionService"  class="FormattingConversionServiceFactoryBean 或 自己开发" ... />

<bean id="validator"  class="LocalValidatorFactoryBean 或 自己开发" ... />

<bean id="messageCodesResolver" class="DefaultMessageCodesResolver 或 自己开发" ... />

如果用户了配置了annotation-driven标签这三个属性值,通常意味着用户开发了自己的实现类,不然没必要显示配置,因为spring会自动采用默认值。还是用个图来表现下这个过程。



三. 数据绑定工厂

顾名思义,这个类的作用是生成DataBinder,下面是它的类结构图。


简单分析下上图。最上面的WebDataBinderFactory接口只定义了一个方法,创建WebDataBinder,方法签名如下。

WebDataBinder createBinder(NativeWebRequest webRequest, Object target, String objectName) throws Exception;
可以看出,创建WeDataBinder时会传入目标对象和目标名称。接下来的DefaultDataBinderFactory实现了创建WebDataBinder的主体逻辑,它会使用持有的WebBindingInitializer对WebDataBinder执行初始化。再接着的InitBinderDataBinderFactory,它会搜索目标对象中所有被"@InitBinder" 注解的方法对象并执行它们。 通常这些方法都会用来配置DataBinder的,可以把这种配置看做目标对象级的配置,而上述的WebBindingInitializer则是对DataBinder的全局配置。最后的ServletRequestDataBinderFactory重写了DefaultDataBinderFactory的WebDataBinder createBinderInstance(...)方法,返回ExtendedServletRequestDataBinder对象。
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值