本站首页    管理页面    写新日志    退出


«October 2025»
1234
567891011
12131415161718
19202122232425
262728293031


公告
 本博客在此声明所有文章均为转摘,只做资料收集使用。

我的分类(专题)

日志更新

最新评论

留言板

链接

Blog信息
blog名称:
日志总数:1304
评论数量:2242
留言数量:5
访问次数:7644009
建立时间:2006年5月29日




[Hibernate]解析Hibernate Validator (1)
软件技术,  电脑与网络

lhwork 发表于 2006/6/7 15:13:14

任何获得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() );    }


阅读全文(2341) | 回复(0) | 编辑 | 精华
 



发表评论:
昵称:
密码:
主页:
标题:
验证码:  (不区分大小写,请仔细填写,输错需重写评论内容!)



站点首页 | 联系我们 | 博客注册 | 博客登陆

Sponsored By W3CHINA
W3CHINA Blog 0.8 Processed in 0.957 second(s), page refreshed 144809782 times.
《全国人大常委会关于维护互联网安全的决定》  《计算机信息网络国际联网安全保护管理办法》
苏ICP备05006046号