欧美性猛交XXXX免费看蜜桃,成人网18免费韩国,亚洲国产成人精品区综合,欧美日韩一区二区三区高清不卡,亚洲综合一区二区精品久久

打開(kāi)APP
userphoto
未登錄

開(kāi)通VIP,暢享免費電子書(shū)等14項超值服

開(kāi)通VIP
解析Hibernate Validator
解析 Hibernate Validator

任何獲得Matrix授權的網(wǎng)站,轉載請保留以下作者信息和鏈接:
作者:icess(作者的blog:http://blog.matrix.org.cn/page/icess)
關(guān)鍵字:Hibernate Validator

在前一篇文章 < Hibernate Validator 簡(jiǎn)介 > http://www.matrix.org.cn/resource/article/44/44153_Hibernate%20Validator%20.html中,我們看到了Hibernate Validator的使用方法,和自定義驗證Annotation的實(shí)現以及錯誤消息的國際化等常見(jiàn)問(wèn)題.

在使用如此優(yōu)雅的屬性驗證框架的同時(shí),你是否想了解她的細節呢?她究竟是怎么實(shí)現的呢? 那么現在就跟隨我來(lái)探探她的內核吧!

Hibernate Validator 可以是一個(gè)獨立的驗證框架, 所以看完這篇分析 你可以把她獨立出來(lái)作為你的個(gè)人驗證框架來(lái)使用了 ^_^(如果你有興趣和時(shí)間的話(huà)). Hibernate Validator 框架里面有兩個(gè)主要的類(lèi): ClassValidator 和InvalidValue 還有一個(gè)接口Validator,在這三個(gè)主要的構件中 最主要的就只有一個(gè) 那就是ClassValidator.另外兩個(gè)是很好理解的..

現在就讓我們開(kāi)始吧. 遵循由淺入深的習慣 我們先看看 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接口就是我們自定義約束的實(shí)現類(lèi)要繼承的接口,該接口在< Hibernate Validator 簡(jiǎn)介 > http://www.matrix.org.cn/resource/article/44/44153_Hibernate%20Validator%20.html 中已經(jīng)討論過(guò)了,請參考.

InvalidValue 類(lèi) 大家看名字就應該可以猜到她的作用了吧. 她就是代表一個(gè)沒(méi)有通過(guò)驗證的錯誤實(shí)例.該類(lèi)定義了一些方法,通過(guò)這些方法你可以取得與該Validator Annotation 有關(guān)的一些參數,如:她所注釋的屬性的值,錯誤消息等等. 該類(lèi)的源代碼如下:

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;
  }

}

然后,就讓我們看看最主要的類(lèi)吧:ClassValidator . 該類(lèi)代碼有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>(); // 保存類(lèi)級別的驗證約束實(shí)現類(lèi)
    memberValidators = new ArrayList<Validator>(); // 保存方法級別的驗證約束實(shí)現類(lèi)
    memberGetters = new ArrayList<Member>();// 保存類(lèi)的成員(字段or方法)和構造函數方法的標識信息
    messages = new HashMap<Validator, String>(); // 利用Map保存與每個(gè)Validator相對應的驗證消息
    childGetters = new ArrayList<Member>();//  保存子類(lèi)的成員(字段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來(lái)得到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的所有超類(lèi)和實(shí)現的接口添加的集合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 ); // 創(chuàng )建方法上的約束實(shí)現類(lèi)(Validator), 參考對該函數的解釋
        Class clazz = method.getReturnType();// 得到該方法的返回類(lèi)型
        createChildValidator( resourceBundle, method, clazz );// 創(chuàng )建子類(lèi)的Validator
      }

      Field[] fields = currClass.getDeclaredFields(); // 掃描Field上面的注釋, 下面和上面Method的實(shí)現一樣
      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 );
      }
    }
  }

  /**
   * 創(chuàng )建內嵌類(lèi)的Validator. 如果該內嵌類(lèi)被Valid Annotation 注釋的話(huà)則 
   * 創(chuàng )建另外一個(gè)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(實(shí)現了AnnotatedElement, GenericDeclaration, Member接口)
   * 得到 方法上的Annotations 然后利用私有方法createValidator(Annotation a)來(lái)創(chuàng )建
   * 每一個(gè)Annotation 的實(shí)現類(lèi) 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 ); // 設置訪(fǎng)問(wèn)屬性
        memberGetters.add( member );
      }
    }
  }

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

  /**
   * 該方法產(chǎn)生了該Annotation的約束實(shí)現類(lèi) 并初始化該類(lèi)對應的消息
   */
  private Validator createValidator(Annotation annotation) {
    try {
      //得到ValidatorClass Annotation 
      ValidatorClass validatorClass = annotation.annotationType().getAnnotation( ValidatorClass.class );
      if ( validatorClass == null ) {
        return null;
      }
      // 然后 利用ValidatorClass Annotation 來(lái)得到里面的值(即實(shí)現該注釋的Class),
      //再利用Class 構造一個(gè)instance
      Validator beanValidator = validatorClass.value().newInstance();
      beanValidator.initialize( annotation ); // 初始化Annotation中的參數(注意:在自定義約束中該方法有你來(lái)實(shí)現)
      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; // 返回 產(chǎn)生的Validator
    }
    catch (Exception e) {
      throw new IllegalArgumentException( "could not instantiate ClassValidator", e );
    }
  }

  public boolean hasValidationRules() {
    return beanValidators.size() != || 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由關(guān)的,
      return EMPTY_INVALID_VALUE_ARRAY; //Avoid circularity
    }
    else {
      circularityState.add( bean );
    }

    if ( !beanClass.isInstance( bean ) ) { // 如果beanClass不是該bean的實(shí)例,則拋出異常
      throw new IllegalArgumentException( "not an instance of: " + bean.getClass() );
    }

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

    for int i = 0; i < beanValidators.size() ; i++ ) { // 驗證類(lèi)級別的約束
      Validator validator = beanValidators.get( i );
      if ( !validator.isValid( bean ) ) { //調用isValid方法,如果沒(méi)有通過(guò)則添加到list<InvalidValue>中
                        //如果是自定義約束則isValid方法 由你來(lái)實(shí)現
        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 ); //取得該約束的驗證實(shí)現類(lèi)
        if ( !validator.isValid( value ) ) {//調用isValid方法,如果沒(méi)有通過(guò)則添加到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++ ) {// 處理子類(lèi)類(lè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 );// 通過(guò)參數value 得到 Class, 然后由Class作為key          //在childClassValidators map中得到其ClassValidator
                                     //如果不存在 則創(chuàng )建新的 ,然后再調用ClassValidator的getInvalidValues方法
          // 注意在調用getInvalidValues方法時(shí) 用到了circularityState 參數, 當調用循環(huán)一周時(shí) 返回(遞歸結束)
          for ( InvalidValue invalidValue : invalidValues ) {
            invalidValue.addParentBean( bean, propertyName );
            results.add( invalidValue ); //添加的結果中
          }
        }
      }
    }

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

  /**
   * 通過(guò)參數value 得到 Class, 然后由Class作為key 在childClassValidators map中得到其ClassValidator
   * 如果不存在 則創(chuàng )建新的 然后返回
   @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.
   * 驗證單個(gè)屬性的約束.
   */
  //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 是否滿(mǎn)足當前屬性的約束.
   */
  //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 );
    }
    else if ( member instanceof Method ) {
      return ( (Method) member ).invoke( bean );
    }
    else {
      throw new AssertionFailure( "Unexpected member: " + member.getClass().getName() );
    }
  }

  public String getPropertyName(Member member) {
    //Do no try to cache the result in a map, it‘s actually much slower (2.x time)
    String propertyName;
    if ( member instanceof Field ) {
      propertyName = member.getName();
    }
    else if ( member instanceof Method ) {
      propertyName = member.getName();
      if ( propertyName.startsWith( "is" ) ) {
        propertyName = Introspector.decapitalize( propertyName.substring( ) );
      }
      else if ( propertyName.startsWith( "get" ) ) {
        propertyName = Introspector.decapitalize( propertyName.substring( ) );
      }
      //do nothing for non getter method, in case someone want to validate a PO Method
    }
    else {
      throw new AssertionFailure( "Unexpected member: " + member.getClass().getName() );
    }
    return propertyName;
  }

  private String replace(String message, Annotation parameters) {
    StringTokenizer tokens = new StringTokenizer( message, "{}"true );
    StringBuilder buf = new StringBuilder( 30 );
    boolean escaped = false;
    while ( tokens.hasMoreTokens() ) {
      String token = tokens.nextToken();
      if "{".equals( token ) ) {
        escaped = true;
      }
      else if "}".equals( token ) ) {
        escaped = false;
      }
      else if ( !escaped ) {
        buf.append( token );
      }
      else {
        Method member;
        try {
          member = parameters.getClass().getMethod( token, (Class[]) null );
        }
        catch (NoSuchMethodException nsfme) {
          member = null;
        }
        if ( member != null ) {
          try {
            buf.append( member.invoke( parameters ) );
          }
          catch (Exception e) {
            throw new IllegalArgumentException( "could not render message", e );
          }
        }
        else if ( messageBundle != null ) {
          String string = messageBundle.getString( token );
          if ( string != null ) buf.append( replace( string, parameters ) );
        }
      }
    }
    return buf.toString();
  }

  /**
   * apply the registred constraints rules on the hibernate metadata (to be applied on DB schema...)
   *該方法是與實(shí)體類(lèi)綁定的 不推薦使用 有興趣的讀者可以自己研究一下
   @param persistentClass hibernate metadata
   */
  public void apply(PersistentClass persistentClass) { 
   //源代碼省略
  }

  /**
   * 斷言該bean 是否符合所有約束. 負責拋出異常
   @param bean
   */
  public void assertValid(T bean) {
    InvalidValue[] values = getInvalidValues( bean );
    if ( values.length > ) {
      throw new InvalidStateException( values );
    }
  }

  /**
   * 該方法應該是序列化ResourceBundle的 為private方法 但并沒(méi)有用到, 不知道為什么 可能以后會(huì )有用
   @param oos
   @throws IOException
   */
  private void writeObject(ObjectOutputStream oos) throws IOException {
    ResourceBundle rb = messageBundle;
    if ( rb != null && ! ( rb instanceof Serializable ) ) {
      messageBundle = null;
      if ( ! defaultResourceBundle )
        log.warn( "Serializing a ClassValidator with a not serializable ResourceBundle: ResourceBundle ignored" );
    }
    oos.defaultWriteObject();
    oos.writeObject( messageBundle );
    messageBundle = rb;
  }

  /**
   * 該方法應該是讀取序列化的ResourceBundle的 為private方法 但并沒(méi)有用到,不知道為什么 可能以后會(huì )有用
   @param ois
   @throws IOException
   @throws ClassNotFoundException
   */
  private void readObject(ObjectInputStream ois) throws IOException, ClassNotFoundException {
    ois.defaultReadObject();
    ResourceBundle rb = (ResourceBundle) ois.readObject();
    if (rb == null) rb = getDefaultResourceBundle();
    initValidator( beanClass, new HashMap<Class, ClassValidator>(), rb );
  }
}

還記得我們在驗證時(shí)候所寫(xiě)的代碼嗎:

 ClassValidator<Person> classValidator = new ClassValidator<Person> (Person.class);
 InvalidValue[] validMessages = classValidator.getInvalidValues(p);

只調用了classValidator的getInvalidValues(p);方法 我們就得到了InvalidValue[] validMessages, 該方法做了什么事情呢? 有上面的注釋看起來(lái)就輕松多了 ^_^.

首先:在你創(chuàng )建ClassValidator時(shí), 會(huì )調用ClassValidator的構造方法 她一供有三個(gè)構造函數 :
  

有兩個(gè)構造函數(一個(gè)傳遞要驗證的類(lèi)為參數,一個(gè)還要加上你自定義的ResourceBundle)來(lái)供我們使用, 還有一個(gè)protected 的構造函數. 在構造函數中都做了寫(xiě)什么呢?

第一: 把要驗證的類(lèi)保存起來(lái),第二:決定使用的消息資源,如果你提供了自己的ResourceBundle 就使用自定義消息,否則使用默認的消息資源.第三: 根據java反射機制,利用Annotation初始化所有的驗證約束類(lèi),然后驗證是否滿(mǎn)足驗證條件.

下面我們來(lái)關(guān)注一下initValidator 方法,看看是如何初始化驗證約束類(lèi)的. 現在請仔細看看 initValidator 里面的注釋.然后在繼續往下看.^_^

 通過(guò)上面的分析,可以看到在 initValidator函數中,初始化了你傳入類(lèi)的所有的約束Annotations 的相關(guān)的東東(如: 其約束驗證實(shí)現類(lèi), 如果有內嵌的類(lèi),如果該類(lèi)被Valid Annotation注釋的話(huà) 也構造一個(gè)內嵌類(lèi)的Validator 并初始化其相關(guān)的東東 如此遞歸執行下去).該函數執行完后,可以說(shuō)構造了一個(gè)以你傳入的類(lèi)為跟的 約束注釋樹(shù)(自創(chuàng )的名詞,不了解也沒(méi)關(guān)系 ^_^),然后由此樹(shù)來(lái)逐個(gè)驗證沒(méi)有個(gè)約束.此時(shí)已經(jīng)具備驗證約束的條件了.你只有調用classValidator.getInvalidValues(p)方法就可以驗證類(lèi)p 上的所有約束了.

 GetInvalidValues()方法有做了什么呢, 現在你要再回到上面看看她的注釋了  ^_^:

怎么樣現在知道 GetInvalidValues 做了什么了吧.她就是取出 約束注釋樹(shù)中的每一個(gè)約束注釋(分為 類(lèi)注釋, 方法注釋, 屬性注釋 和內嵌類(lèi)注釋 (也就是類(lèi)里面的類(lèi)屬性)),并驗證相應的成員是否滿(mǎn)足該約束注釋的要求,也就是調用Validator的isValid() 方法.最后用不滿(mǎn)足要求的 成員信息構造InvalidValue 數組 并返. ClassValidator 類(lèi)我們基本上已經(jīng)講解完了,剩下的該Validatro里面的就是一些內建的約束Annotation和約束驗證實(shí)現類(lèi)了,這些看看前一篇文章就明白怎么回事了.到此 HibernateValidator 框架基本上分析完了. 通過(guò)分析該框架.讓我看到了Annotation的一種高級用法的實(shí)現機制,和反射機制的巧妙應用,以及幾個(gè)巧妙的設計模式(我就不在舉例了 大家可以相互探討一下). 你從中學(xué)到了什么呢?

對想把Hibernate Validator做成一個(gè)獨立框架的幾點(diǎn)說(shuō)明:

1.去掉apply 函數.

2. 在getPropertyName 和 getMemberValue 中 如果得到的值為null 則拋出org.hibernate.AssertionFailure異常. 可以重寫(xiě)該異常,或者從Hibernate源代碼中提取(建議重寫(xiě)).

3.用到了Hibernate.isPropertyInitialized(Object o,String name)方法 判斷該類(lèi)(o)的屬性(name)是否以及加載的, 該函數的doc 注釋為 Check if the property is initialized. If the named property does not exist or is not persistent, this method always returns true.可以替換為判斷該屬性(name)是否為null, null即代表沒(méi)有賦初值(可能違反約束);否則驗證該值是否違反約束.

4.里面還用到了org.hibernate.util.IdentitySet 一個(gè)set實(shí)現,可以自己實(shí)現或者從Hibernate中提取(推薦提取);

這樣一個(gè)獨立的Validation frameWork 就出來(lái)了. 不依賴(lài)任何第三方代碼,完全可以作為你自己的驗證框架在項目中使用.

PS: 關(guān)于在實(shí)體類(lèi)上(持久化層)使用Validator是否有好處,大家可以到如下連接看看:http://www.hibernate.org.cn/viewtopic.php?t=18131

我也在Matrix Hibernate 論壇開(kāi)了一討論貼 請大家走過(guò)路過(guò)都看看:http://www.matrix.org.cn/thread.shtml?topicId=36657&forumId=23 讓我們更高效的使用 Validator.

 

本站僅提供存儲服務(wù),所有內容均由用戶(hù)發(fā)布,如發(fā)現有害或侵權內容,請點(diǎn)擊舉報。
打開(kāi)APP,閱讀全文并永久保存 查看更多類(lèi)似文章
猜你喜歡
類(lèi)似文章
Hibernate Validation 中文
ibatis支持枚舉類(lèi)型
Jedis連接池
Dissect Eclipse Plugin Framework
如何手寫(xiě)Mybatis?
c#單態(tài)設計模式
更多類(lèi)似文章 >>
生活服務(wù)
分享 收藏 導長(cháng)圖 關(guān)注 下載文章
綁定賬號成功
后續可登錄賬號暢享VIP特權!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服

欧美性猛交XXXX免费看蜜桃,成人网18免费韩国,亚洲国产成人精品区综合,欧美日韩一区二区三区高清不卡,亚洲综合一区二区精品久久