`
icess
  • 浏览: 253415 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

解析 Hibernate Validator

阅读更多

任何获得Matrix授权的网站,转载请保留以下作者信息和链接:
作者:icess(作者的blog:http://blog.matrix.org.cn/page/icess)
关键字:Hibernate Validator

在前一篇文章 < Hibernate Validator 简介 > http://www.matrix.org.cn/resource/article/44/44153_Hibernate%20Validator%20.html中,我们看到了Hibernate Validator的使用方法,和自定义验证Annotation的实现以及错误消息的国际化等常见问题.

在使用如此优雅的属性验证框架的同时,你是否想了解她的细节呢?她究竟是怎么实现的呢? 那么现在就跟随我来探探她的内核吧!

Hibernate Validator 可以是一个独立的验证框架, 所以看完这篇分析 你可以把她独立出来作为你的个人验证框架来使用了 ^_^(如果你有兴趣和时间的话). Hibernate Validator 框架里面有两个主要的类: ClassValidator 和InvalidValue 还有一个接口Validator,在这三个主要的构件中 最主要的就只有一个 那就是ClassValidator.另外两个是很好理解的..

现在就让我们开始吧. 遵循由浅入深的习惯 我们先看看 Validator 接口吧. 其代码如下:

import  java.lang.annotation.Annotation;

/**
  * A constraint validator for a particular annotation
  *
  *  @author  Gavin King
  */
public interface  Validator<A  extends  Annotation> {
   /**
    * does the object/element pass the constraints
    */
   public boolean  isValid(Object value);

   /**
    * Take the annotations values
    *  @param  parameters
    */
   public void  initialize(A parameters);
}

Validator接口就是我们自定义约束的实现类要继承的接口,该接口在< Hibernate Validator 简介 > http://www.matrix.org.cn/resource/article/44/44153_Hibernate%20Validator%20.html 中已经讨论过了,请参考.

InvalidValue 类 大家看名字就应该可以猜到她的作用了吧. 她就是代表一个没有通过验证的错误实例.该类定义了一些方法,通过这些方法你可以取得与该Validator Annotation 有关的一些参数,如:她所注释的属性的值,错误消息等等. 该类的源代码如下:

import  java.io.Serializable;

/**
  * A single violation of a class level or method level constraint.
  *
  *  @author  Gavin King
  */
public class  InvalidValue  implements  Serializable {
   private final  String message;
   private final  Object value;
   private final  String propertyName;
   private final  Class beanClass;
   private final  Object bean;
   private  Object rootBean;

   public  Object getRootBean() {
     return  rootBean;
   }

   public  String getPropertyPath() {
     return  propertyPath;
   }

   private  String propertyPath;

   public  InvalidValue(String message, Class beanClass, String propertyName, Object value, Object bean) {
     this .message = message;
     this .value = value;
     this .beanClass = beanClass;
     this .propertyName = propertyName;
     this .bean = bean;
     this .rootBean = bean;
     this .propertyPath = propertyName;
   }

   public void  addParentBean(Object parentBean, String propertyName) {
     this .rootBean = parentBean;
     this .propertyPath = propertyName +  "."  +  this .propertyPath;
   }

   public  Class getBeanClass() {
     return  beanClass;
   }

   public  String getMessage() {
     return  message;
   }

   public  String getPropertyName() {
     return  propertyName;
   }

   public  Object getValue() {
     return  value;
   }

   public  Object getBean() {
     return  bean;
   }

   public  String toString() {
     return  propertyName +  ' '  + message;
   }

}

然后,就让我们看看最主要的类吧:ClassValidator . 该类代码有400余行,我都做了详细的注释如下:

import  该部分省略了;


/**
  * Engine that take a bean and check every expressed annotation restrictions
  *
  *  @author  Gavin King
  */
public class  ClassValidator<T>  implements  Serializable {
   private static  Log log = LogFactory.getLog( ClassValidator. class  );
   private static final  InvalidValue[] EMPTY_INVALID_VALUE_ARRAY =  new  InvalidValue[]{};
   private final  Class<T> beanClass;
   private transient  ResourceBundle messageBundle;
   private transient boolean  defaultResourceBundle;

   private final transient  Map<Class, ClassValidator> childClassValidators;
   private transient  List<Validator> beanValidators;
   private transient  List<Validator> memberValidators;
   private transient  List<Member> memberGetters;
   private transient  Map<Validator, String> messages;
   private transient  List<Member> childGetters;
   private static final  String DEFAULT_VALIDATOR_MESSAGE =  "org.hibernate.validator.resources.DefaultValidatorMessages" ;


   /**
    * create the validator engine for this bean type
    */
   public  ClassValidator(Class<T> beanClass) {
     this ( beanClass,  null  );
   }

   /**
    * create the validator engine for a particular bean class, using a resource bundle
    * for message rendering on violation
    */
   public  ClassValidator(Class<T> beanClass, ResourceBundle resourceBundle) {
     this ( beanClass, resourceBundle,  new  HashMap<Class, ClassValidator>() );
   }

   protected  ClassValidator(
       Class<T> beanClass, ResourceBundle resourceBundle, Map<Class, ClassValidator> childClassValidators
   ) {
     this .beanClass = beanClass;
     this .messageBundle = resourceBundle ==  null  ?
         getDefaultResourceBundle() :
         resourceBundle;
     this .childClassValidators = childClassValidators;
     initValidator( beanClass, childClassValidators,  this .messageBundle );  //重要的是该初始化函数
   }

   private  ResourceBundle getDefaultResourceBundle() {
     ResourceBundle rb;
     try  {
       rb = ResourceBundle.getBundle(  "ValidatorMessages"  );
     }
     catch ( MissingResourceException e) {
       //the user did not override the default ValidatorMessages
       log.debug(  "ResourceBundle ValidatorMessages not found. Delegate to "  + DEFAULT_VALIDATOR_MESSAGE);
       rb = ResourceBundle.getBundle( DEFAULT_VALIDATOR_MESSAGE );
     }
     defaultResourceBundle =  true ;
     return  rb;
   }

   private void  initValidator(
       Class<T> beanClass, Map<Class, ClassValidator> childClassValidators,
       ResourceBundle resourceBundle
   ) {
     beanValidators =  new  ArrayList<Validator>();  // 保存类级别的验证约束实现类
     memberValidators =  new  ArrayList<Validator>();  // 保存方法级别的验证约束实现类
     memberGetters =  new  ArrayList<Member>(); // 保存类的成员(字段or方法)和构造函数方法的标识信息
     messages =  new  HashMap<Validator, String>();  // 利用Map保存与每个Validator相对应的验证消息
     childGetters =  new  ArrayList<Member>(); //  保存子类的成员(字段or方法)和构造函数方法的标识信息

     childClassValidators.put( beanClass,  this  );  //map Map<Class, ClassValidator> childClassValidators;
     Annotation[] classAnnotations = beanClass.getAnnotations();
     for int  i =  0 ; i < classAnnotations.length ; i++ ) {
       Annotation classAnnotation = classAnnotations[i];
      Validator beanValidator = createValidator( classAnnotation ); //根据Annotation来得到Validator,参考对该函数的解释
       if  ( beanValidator !=  null  ) beanValidators.add( beanValidator ); //保存该Validator
     }
     //build the class hierarchy to look for members in
     Collection<Class> classes =  new  HashSet<Class>();
     addSuperClassesAndInterfaces( beanClass, classes ); //把beanClass的所有超类和实现的接口添加的集合classes中

     //Check on all selected classes
     for  ( Class currClass : classes ) {
       Method[] methods = currClass.getDeclaredMethods(); // 扫描Method上面的注释
       for int  i =  0 ; i < methods.length ; i++ ) {
         Method method = methods[i];
         createMemberValidator( method );  // 创建方法上的约束实现类(Validator), 参考对该函数的解释
         Class clazz = method.getReturnType(); // 得到该方法的返回类型
         createChildValidator( resourceBundle, method, clazz ); // 创建子类的Validator
       }

       Field[] fields = currClass.getDeclaredFields();  // 扫描Field上面的注释, 下面和上面Method的实现一样
       for int  i =  0 ; i < fields.length ; i++ ) {
         Field field = fields[i];
         createMemberValidator( field );
         Class clazz = field.getType();
         createChildValidator( resourceBundle, field, clazz );
       }
     }
   }

   private void  addSuperClassesAndInterfaces(Class clazz, Collection<Class> classes) {
     for  ( Class currClass = clazz; currClass !=  null  ; currClass = currClass.getSuperclass() ) {
       if  ( ! classes.add( currClass ) )  return ;
       Class[] interfaces = currClass.getInterfaces();
       for  (Class interf : interfaces) {
         addSuperClassesAndInterfaces( interf, classes );
       }
     }
   }

   /**
    * 创建内嵌类的Validator. 如果该内嵌类被Valid Annotation 注释的话则 
    * 创建另外一个ClassValidator
    *  @param  resourceBundle
    *  @param  member
    *  @param  clazz
    */
   private void  createChildValidator(ResourceBundle resourceBundle, Member member, Class clazz) {
     if  ( ( (AnnotatedElement) member ).isAnnotationPresent( Valid. class  ) ) {
       setAccessible( member );
       childGetters.add( member );
       if  ( !childClassValidators.containsKey( clazz ) ) {
         new  ClassValidator( clazz, resourceBundle, childClassValidators );
       }
     }
   }

   /**
    * 利用传入的Method(实现了AnnotatedElement, GenericDeclaration, Member接口)
    * 得到 方法上的Annotations 然后利用私有方法createValidator(Annotation a)来创建
    * 每一个Annotation 的实现类 Validator 并保存Validator和member
    *  @param  member
    */
   private void  createMemberValidator(Member member) {
     Annotation[] memberAnnotations = ( (AnnotatedElement) member ).getAnnotations();
     for int  j =  0 ; j < memberAnnotations.length ; j++ ) {
       Annotation methodAnnotation = memberAnnotations[j];
       Validator propertyValidator = createValidator( methodAnnotation );
       if  ( propertyValidator !=  null  ) {
         memberValidators.add( propertyValidator );
         setAccessible( member );  // 设置访问属性
         memberGetters.add( member );
       }
     }
   }

   private static void  setAccessible(Member member) {
     if  ( !Modifier.isPublic( member.getModifiers() ) ) {
       ( (AccessibleObject) member ).setAccessible(  true  );
     }
   }

   /**
    * 该方法产生了该Annotation的约束实现类 并初始化该类对应的消息
    */
   private  Validator createValidator(Annotation annotation) {
     try  {
       //得到ValidatorClass Annotation 
       ValidatorClass validatorClass = annotation.annotationType().getAnnotation( ValidatorClass. class  );
       if  ( validatorClass ==  null  ) {
         return null ;
       }
       // 然后 利用ValidatorClass Annotation 来得到里面的值(即实现该注释的Class),
       //再利用Class 构造一个instance
       Validator beanValidator = validatorClass.value().newInstance();
       beanValidator.initialize( annotation );  // 初始化Annotation中的参数(注意:在自定义约束中该方法有你来实现)
       String messageTemplate = (String) annotation.getClass()
           .getMethod(  "message" , (Class[])  null  )
           .invoke( annotation );   // 取得 constraint descriptor  中的message 的值
       String message = replace( messageTemplate, annotation );  // 初始化取得的模板消息 请参考 replace函数
       messages.put( beanValidator, message );  // 把message 放在map中,以便使用
       return  beanValidator;  // 返回 产生的Validator
     }
     catch  (Exception e) {
       throw new  IllegalArgumentException(  "could not instantiate ClassValidator" , e );
     }
   }

   public boolean  hasValidationRules() {
     return  beanValidators.size() !=  0  || memberValidators.size() !=  0 ;
   }

   /**
    * apply constraints on a bean instance and return all the failures.
    */
   public  InvalidValue[] getInvalidValues(T bean) {
     return this .getInvalidValues( bean,  new  IdentitySet() );
   }

   /**
    * apply constraints on a bean instance and return all the failures.
    */
   protected  InvalidValue[] getInvalidValues(T bean, Set<Object> circularityState) {
     if  ( circularityState.contains( bean ) ) {   // 该if else 是和Hibernate Core由关的,
       return  EMPTY_INVALID_VALUE_ARRAY;  //Avoid circularity
     }
     else  {
       circularityState.add( bean );
     }

     if  ( !beanClass.isInstance( bean ) ) {  // 如果beanClass不是该bean的实例,则抛出异常
       throw new  IllegalArgumentException(  "not an instance of: "  + bean.getClass() );
     }

     List<InvalidValue> results =  new  ArrayList<InvalidValue>();

     for int  i =  0 ; i < beanValidators.size() ; i++ ) {  // 验证类级别的约束
       Validator validator = beanValidators.get( i );
       if  ( !validator.isValid( bean ) ) {  //调用isValid方法,如果没有通过则添加到list<InvalidValue>中
                         //如果是自定义约束则isValid方法 由你来实现
         results.add(  new  InvalidValue( messages.get( validator ), beanClass, null, bean, bean ) );
       }
     }

     for int  i =  0 ; i < memberValidators.size() ; i++ ) { //验证方法级别的约束
       Member getter = memberGetters.get( i );
       if Hibernate.isPropertyInitialized(bean, getter.getName() ) ) { // ? 检查该属性是否已初始化
         Object value = getMemberValue( bean, getter ); //利用反射 取得该属性的值
         Validator validator = memberValidators.get( i );  //取得该约束的验证实现类
         if  ( !validator.isValid( value ) ) { //调用isValid方法,如果没有通过则添加到list<InvalidValue>中
           String propertyName = getPropertyName( getter );
           results.add(  new  InvalidValue( messages.get( validator ), beanClass, propertyName, value, bean ) );
         }
       }
     }

     for int  i =  0 ; i < childGetters.size() ; i++ ) { // 处理子类类
       Member getter = childGetters.get( i );
       if Hibernate.isPropertyInitialized(bean, getter.getName() ) ) {  //检查该属性是否已初始化
         Object value = getMemberValue( bean, getter );
         if  ( value !=  null  && Hibernate.isInitialized( value ) ) {
           String propertyName = getPropertyName( getter );
           InvalidValue[] invalidValues = getClassValidator( value )
               .getInvalidValues( value, circularityState ); // 通过参数value 得到 Class, 然后由Class作为key          //在childClassValidators map中得到其ClassValidator
                                      //如果不存在 则创建新的 ,然后再调用ClassValidator的getInvalidValues方法
           // 注意在调用getInvalidValues方法时 用到了circularityState 参数, 当调用循环一周时 返回(递归结束)
           for  ( InvalidValue invalidValue : invalidValues ) {
             invalidValue.addParentBean( bean, propertyName );
             results.add( invalidValue );  //添加的结果中
           }
         }
       }
     }

     return  results.toArray(  new  InvalidValue[results.size()] );  //返回InvalidValue数组
   }

   /**
    * 通过参数value 得到 Class, 然后由Class作为key 在childClassValidators map中得到其ClassValidator
    * 如果不存在 则创建新的 然后返回
    *  @param  value
    *  @return
    */
   private  ClassValidator getClassValidator(Object value) {
     Class clazz = value.getClass();
     ClassValidator validator = childClassValidators.get( clazz );
     if  ( validator ==  null  ) {  //handles polymorphism
       validator =  new  ClassValidator( clazz );
     }
     return  validator;
   }

   /**
    * Apply constraints of a particular property on a bean instance and return all the failures.
    * Note this is not recursive.
    * 验证单个属性的约束.
    */
   //TODO should it be recursive ?
   public  InvalidValue[] getInvalidValues(T bean, String propertyName) {
     List<InvalidValue> results =  new  ArrayList<InvalidValue>();

     for int  i =  0 ; i < memberValidators.size() ; i++ ) {
       Member getter = memberGetters.get( i );
       if  ( getPropertyName( getter ).equals( propertyName ) ) { // 验证该属性的约束
         Object value = getMemberValue( bean, getter );
         Validator validator = memberValidators.get( i );
         if  ( !validator.isValid( value ) ) {
           results.add(  new  InvalidValue( messages.get( validator ), beanClass, propertyName, value, bean ) );
         }
       }
     }

     return  results.toArray(  new  InvalidValue[results.size()] );
   }

   /**
    * Apply constraints of a particular property value of a bean type and return all the failures.
    * The InvalidValue objects returns return null for InvalidValue#getBean() and InvalidValue#getRootBean()
    * Note this is not recursive.
    * 验证 value 是否满足当前属性的约束.
    */
   //TODO should it be recursive?
   public  InvalidValue[] getPotentialInvalidValues(String propertyName, Object value) {
     List<InvalidValue> results =  new  ArrayList<InvalidValue>();

     for int  i =  0 ; i < memberValidators.size() ; i++ ) {
       Member getter = memberGetters.get( i );
       if  ( getPropertyName( getter ).equals( propertyName ) ) {
         Validator validator = memberValidators.get( i );
         if  ( !validator.isValid( value ) ) {
           results.add(  new  InvalidValue( messages.get( validator ), beanClass, propertyName, value,  null  ) );
         }
       }
     }

     return  results.toArray(  new  InvalidValue[results.size()] );
   }

   private  Object getMemberValue(T bean, Member getter) {
     Object value;
     try  {
       value = getValue( getter, bean );
     }
     catch  (Exception e) {
       throw new  IllegalStateException(  "Could not get property value" , e );
     }
     return  value;
   }

   private  Object getValue(Member member, T bean)  throws  IllegalAccessException, InvocationTargetException {
     if  ( member  instanceof  Field ) {
       return  ( (Field) member ).get( bean );
     }
#fff

分享到:
评论

相关推荐

    hibernate-validator-5.0.1.final-sources.jar源码

    《深入解析Hibernate Validator 5.0.1.Final源码》 Hibernate Validator是Java Bean Validation规范的实现,它提供了一套强大的数据校验框架,使得开发者可以方便地对Java对象的属性进行验证。5.0.1.Final是...

    hibernate_validator 官方参考文档

    《深入理解Hibernate Validator:官方参考文档精要》 在探讨Hibernate Validator之前,我们先来了解一下其背景与核心价值。Hibernate Validator是Java Bean Validation(JSR 303)的参考实现,它为开发者提供了一套...

    hibernate-validator-5.2.4.Final.jar

    《Hibernate Validator 深度解析》 Hibernate Validator 是一个基于 Bean Validation 规范的实现,是 Hibernate 项目的一部分,主要用于进行 Java 对象的验证。它提供了丰富的约束注解和自定义验证逻辑,使得开发者...

    hibernate-validator-4.0.1.GA-dist

    《Hibernate Validator 深度解析:4.0.1.GA 版本详解》 Hibernate Validator,作为Java世界中的一款强大且广泛使用的验证框架,极大地简化了应用中的数据验证过程。本文将深入探讨 Hibernate Validator 4.0.1.GA ...

    hibernate-validator-5.0.0.CR2-dist.zip

    《Hibernate Validator 深入解析与应用》 Hibernate Validator 是一个强大的Java Bean验证框架,它基于JSR 303(Bean Validation)和JSR 349(Bean Validation 1.1)标准,提供了丰富的验证注解和自定义验证规则。...

    hibernate-validator.rar

    《Hibernate Validator 深度解析与应用实践》 Hibernate Validator 是一个基于 Java Bean Validation 规范的开源验证框架,它是 Hibernate 项目的一部分,主要用于在 Java 应用程序中实现数据校验。本篇文章将深入...

    hibernate-validator-reference4.2final

    Hibernate Validator提供了扩展点,如自定义约束注解、自定义消息解析器、自定义约束定义等,使开发者可以根据需求进行定制化开发。 总结,Hibernate Validator 4.2.0.Final是Java开发者在处理数据验证时的得力工具...

    hibernate_validator 4 中文参考

    集成的过程中,Hibernate Validator提供了一些机制来解决集成中可能遇到的问题,比如验证提供者解析器(ValidationProviderResolver)的使用。此外,Hibernate Validator还提供了XML配置方式,使得开发者可以通过XML...

    (精品推荐)hibernate-validator-3.1.0.GA.zip

    《深入理解Hibernate Validator 3.1.0.GA:附带源码与实战解析》 Hibernate Validator 是一个基于 Bean Validation 规范的实现,它为Java应用提供了强大的数据验证功能。在3.1.0.GA版本中,该框架不仅包含了完整的...

    hibernate-validator-6.0.2

    《Hibernate Validator 深度解析与应用指南》 Hibernate Validator 是一个基于 Java Bean Validation 规范的实现,它为 Java 应用程序提供了强大的验证框架。在本文中,我们将深入探讨 Hibernate Validator 的核心...

    hibernate-validator-4.3.1.Final-sources

    《Hibernate Validator 深度解析:4.3.1.Final源码剖析》 Hibernate Validator是Java Bean Validation标准的重要实现,它为Java应用程序提供了强大的数据校验功能。在这个版本4.3.1.Final中,我们有机会深入源码,...

    hibernate-validator

    **Hibernate Validator 深度解析** Hibernate Validator 是一个基于 Java Bean Validation 规范的实现,它是 Hibernate 项目的一部分,主要用于校验对象的属性值。它提供了丰富的注解和API,帮助开发者在Java应用中...

    hibernate-validator示例demo

    在IT行业中,尤其是在Java开发领域,`Hibernate Validator`是一个至关重要的工具,它是JSR-303/JSR-349(Java Bean Validation)规范的实现,用于验证对象的属性值。`SpringMVC`是Spring框架的一部分,用于处理Web...

    hibernate-validator-5.2.1.Final-dist

    《Hibernate Validator 深度解析与应用》 Hibernate Validator 是 Hibernate 社区提供的一款强大的Java Bean验证框架,它基于JSR-303(Bean Validation)标准,为开发者提供了便捷的验证API,使得数据验证过程更为...

    hibernate-validator-4.1.0.Final-dist.tar.gz

    《Hibernate Validator 深度解析:4.1.0.Final 版本解析与应用》 Hibernate Validator 是Java Bean Validation的实现,它提供了一种在应用程序中进行数据验证的规范和框架。作为Hibernate ORM框架的一部分,它使得...

    hibernate-validator-annotation-processor-4.3.1.final-sources.jar.zip

    《Hibernate Validator注解处理器4.3.1.Final源码解析》 Hibernate Validator是一款强大的Java Bean验证框架,它是JSR 303/JSR 349规范的实现,用于在运行时验证对象的属性。这个压缩包“hibernate-validator-...

    hibernate-validator-5.0.3.Final

    《Hibernate Validator 5.0.3.Final:深入解析企业级数据校验框架》 Hibernate Validator,作为Java世界中的一款强大且广泛使用的数据校验框架,是Bean Validation规范的实现,它极大地简化了应用程序的数据验证...

    hibernate-validator-6.0.5.Final-dist.zip

    《Hibernate Validator 深度解析与应用实践》 Hibernate Validator 是Java世界中一款强大的验证框架,它是JSR 303(Bean Validation)和JSR 349(Bean Validation 1.1)规范的参考实现。在hibernate-validator-...

    hibernate-validator数据校验jar集合

    6. **可扩展性**:`Hibernate Validator`允许自定义约束的声明和解析,以及验证器的实现,以满足特定需求。 7. **与其他框架集成**:`Hibernate Validator`不仅可以在独立应用中使用,还能够与Spring、Hibernate ...

    hibernate-validator-4.2.0.Final-dist

    《Hibernate Validator 深度解析:4.2.0.Final版详解》 Hibernate Validator,作为Java Bean Validation标准的重要实现,是开发过程中不可或缺的验证工具。4.2.0.Final版本是其历史上的一个重要里程碑,它在功能、...

Global site tag (gtag.js) - Google Analytics