这一步骤把该Bean上的字段、方法等等需要校验的项都提取出来。就拿上例中的Demo校验Person类来说,最终得出的BeanConfiguration如下:(两个)
这是直观的结论,可以看到仅仅是一个简单的类其实所包含的项是挺多的。
此处说一句:项是有这么多,但是并不是每一个都需要走验证逻辑的。因为毕竟大多数项上面并没有约束(注解),大多数ConstrainedElement.getConstraints()为空嘛~
总得来说,我个人建议不能光只记忆结论,因为那很容易忘记,所以还是得稍微深入一点,让记忆更深刻吧。那就从下面四个方面深入:
检索Field:getFieldMetaData( beanClass )拿到本类所有字段Field:clazz.getDeclaredFields()
把每个Field都包装成ConstrainedElement存放起来~~~
1. 注意:此步骤完成了对每个Field上标注的注解进行了保存
拿到本类所有的方法Method:clazz.getDeclaredMethods()
排除掉静态方法和合成(isSynthetic)方法
把每个Method都转换成一个ConstrainedExecutable装着~~(ConstrainedExecutable也是个ConstrainedElement)。在此期间它完成了如下事(方法和构造器都复杂点,因为包含入参和返回值):
1. 找到方法上所有的注解保存起来
2. 处理入参、返回值(包括自动判断是作用在入参还是返回值上)
完全同处理Method,略
检索Type:getClassLevelConstraints( beanClass )找打标注在此类上的所有的注解,转换成ConstraintDescriptor
对已经找到每个ConstraintDescriptor进行处理,最终都转换Set<MetaConstraint<?>>这个类型
1.
把Set<MetaConstraint<?>>用一个ConstrainedType包装起来(ConstrainedType是个ConstrainedElement)
==关于级联校验此处补充说明一点,处理Type,都会处理级联校验情况,并且还是递归处理:==
也就是这个方法(课件@Valid在此处生效):
这里对我们理解级联校验最重要的一句是:annotatedElement.isAnnotationPresent(Valid.class)。也就是说:若元素被此注解标注了,那就证明需要对它进行级联校验,这就是JSR定位@Valid的作用~
Spring提升了它???请关注后文Spring对它的应用吧~
ConstraintValidator.isValid()调用处