您的位置:首页 > 编程语言 > Java开发

Spring3.1.0实现原理分析(十五).MVC验证器模块

2017-06-27 00:00 627 查看
大家好,今天我们分析下Spring的验证器模块(Validator),照理说验证器模块并非专用于web应用,但是通常还是在web应用中使用,所以我们还是在MVC这个大主题中讨论验证器模块吧。spring验证器验证什么东西呢?用于验证对象的各属性值是否符合要求,如取值范围要求、格式要求、长度要求等等。验证器在什么时候执行验证呢?在对象各属性被赋值之后。验证器是手动触发还是自动触发?手动,因为校验规则属于业务逻辑范畴,spring不会强迫用户必须执行验证。

之所以分析验证器,是为了以后更好的理解数据绑定器(DataBinder),数据绑定器主要由两部分构成,分别是绑定结果(BindingResult)和验证器。按照惯例,上张类结构图,然后根据图进行讲解。



从上图可以看出,整个验证模块的灵魂是最上面的三个接口,这三个接口定义了验证器可能具备的功能。中间的SpringValidatorAdapter类则是模块的中枢,它实现了验证的核心功能。最下面的LocalValidatorFactoryBean类是集大成者,最终是使用它来执行验证功能的,它也是Spring MVC默认的验证器。

1. Validator

这个接口定义了两个方法,分别是 “是否支持对指定类型的验证”(这个方法派生类的实现逻辑就是返回true,支持对任意类型的验证) 和 “执行验证”。

2. SmartValidator

这个接口在超接口的基础上又增加了一个方法,“执行验证时可传入分组”。这里的分组就是jsr303规范中定义的groups,它的作用是控制验证顺序或只对部分字段执行验证。官方原文如下“Groups are typically used to control the order in which constraints are evaluated, or to perform validation of the partial state of a JavaBean”。

3. javax.validation.Validator

这个是jsr303的接口,这里先剧透下,其实spring并没有编写自己的验证器,而是直接使用jsr303验证器。让派生类实现这个接口的目的是,我猜测应该是为了可以使用两种API引用验证器。

4. SpringValidatorAdapter

这个类上面也说了,是整个验证模块的中枢,实现了验证的主体功能。它持有jsr303验证器,通过它实现验证功能。因此对于验证功能本身spring是不需要处理什么的,调用jsr303验证器的validate(object)方法一行代码搞定。那么SpringValidatorAdapter需要处理什么呢?需要处理的是验证失败信息的转换。把jsr303的失败信息对象转换成spring内部的验证失败信息对象,具体就是FieldError,然后把FieldError添加到Errors接口的实现类,其实就是绑定结果对象。

FieldError类的本质是封装了解析一个国际化消息所需要的信息,具体包含消息key数组、实参数组、默认消息。也就是说,spring转换验证失败消息的目的是要使用自己的国际化模块。

5. LocalValidatorFactoryBean

这个类的主要作用是创建jsr303验证器工厂,然后通过验证器工厂创建jsr303验证器,把验证器赋值给超类, SpringValidatorAdapter是持有jsr303验证器的。LocalValidatorFactoryBean可以干预创建一个怎样的jsr303验证器工厂,它定义了很多成员变量,用户可以给这些变量注入值。

private Class providerClass;

private MessageInterpolator messageInterpolator;

private TraversableResolver traversableResolver;

private ConstraintValidatorFactory constraintValidatorFactory;

重点说下constraintValidatorFactory,我们知道开发一个自定义jsr303约束,大致分为两个步骤。首先创建自定义约束注解对象,然后开发对应的约束验证对象。constraintValidatorFactory就是用来获取自定义的约束验证对象的,它的默认值是SpringConstraintValidatorFactory,可以联想到,通过spring这个bean工厂获取自定义约束验证对象。

LocalValidatorFactoryBean在afterPropertiesSet()方法中创建jsr303验证器工厂的,这也是它实现InitializingBean接口的目的。

最后总结下,spring并没有开发自己的验证器, 因为HibernateValidator已经做的很好了,spring直接拿来主义就行。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  Validator Spring