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