AspectJ切面自定义注解实现参数分组校验——基础概念(1)
- 一、环境
- 二、validation-api源码解读
- 2-1.Default源码解读
- 2-2.valid源码解读
- 2-3.Validation源码解读
 
 
一、环境
maven
需要引入的依赖:
<dependency><groupId>javax.validation</groupId><artifactId>validation-api</artifactId><version>2.0.1.Final</version>
</dependency>
二、validation-api源码解读
通常使用validation-api对参数校验会使用@valid注解配合@NotBlank、@NotNull等注解使用进行参数校验。
	@NotNull(message = "金额不能为空")private BigDecimal amount;/*** 币种*/@NotBlank(message="币种不能为空")private String currency;
但是,当前@valid只支持对Default组进行校验。也就是说,不支持对参数进行分多个组校验。
2-1.Default源码解读
Default接口Reference如下,
javax.validation.groups.Default
public interface Default {
}
Default源码阐述如下,
Default Bean Validation group.
Unless a list of groups is explicitly defined:
constraints belong to the Default group
validation applies to the Default group
Most structural constraints should belong to the default group.
可以看出,constraints(指@NotBlank、NotNull等注解)默认是归属默认组,Validation验证的也只是默认组。
除非明确的定义了其他一些组。即Valid注解只是针对默认组进行验证。
2-2.valid源码解读
Valid注解Reference如下,
javax.validation.Valid
@Target({ METHOD, FIELD, CONSTRUCTOR, PARAMETER, TYPE_USE })
@Retention(RUNTIME)
@Documented
public @interface Valid {
}
Valid源码阐述如下,
Marks a property, method parameter or method return type for validation cascading.
Constraints defined on the object and its properties are be validated when the property, method parameter or method return type is validated.
This behavior is applied recursively.
可以看出,当constraints与@valid注解做一种关联映射时,虽然constraints是定义在object侧,但是对于使用了@valid注解的属性、方法参数、方法返回参数,对应的object侧定义的constraints,均会进行校验。这种行为应用是一种递归形式。
2-3.Validation源码解读
Validation类Reference如下,
javax.validation.Validation
Validation类的构成如下,

Validation是支持用户自定义,来对Bean进行验证的一个类。源码提供了3种版本的思路:
1)思路一
直接构造默认的ValidatorFactory,
ValidatorFactory factory = Validation.buildDefaultValidatorFactory();
这种情况下,校验的提供者,可以通过XML配置定义;如果没有定义,会使用ValidationProviderResolver返回的第一个ValidationProvider作为校验的提供者。ValidationProviderResolver可以保证运行时环境的可用性。
2)思路二
当然,也可以使用固定的ValidationProviderResolver,即自己实现一个ValidationProviderResolver来作为providerResolver(ValidationProviderResolver resolver)的参数(如下:new MyResolverStrategy())。
Configuration<?> configuration = Validation.byDefaultProvider().providerResolver( new MyResolverStrategy() ).configure();ValidatorFactory factory = configuration.buildValidatorFactory();   
3)思路三
对Configuration实现一个自定义的子接口,来作为特定的校验提供者(如下:ACMEConfiguration)。
可以实现ValidationProvider接口的自定义的子接口(如下:ACMEProvider),作为byProvider(Class<U> providerType)的参数。
ACMEConfiguration configuration = Validation.byProvider(ACMEProvider.class).providerResolver( new MyResolverStrategy() )  // optionally set the provider resolver.configure();ValidatorFactory factory = configuration.buildValidatorFactory();  
值得注意的是,上述构建的ValidatorFactory需要被缓存,使Validator消费者共享使用同一个ValidatorFactory。
javax.validation.ValidatorFactory#getValidator