th 属性声明
@Retention(RetentionPolicy.RUNTIME)
public @interface MaxLength {
int length() default 0;
}
MaxLength 验证程序的实际功能存在于两个类中:名为 Validator 的一个抽象类及其具体实现 MaxLengthValidator。Validator 类出现在清单 6 中:
清单 6. 提取基于属性的 Validator 类
public abstract class Validator {
public void validate(Object obj) throws ValidationException {
Class clss = obj.getClass();
for(Method method : clss.getMethods())
if (method.isAnnotationPresent(getAnnotationType()))
validateMethod(obj, method, method.getAnnotation(getAnnotationType ()));
}
protected abstract Class getAnnotationType();
protected abstract void validateMethod(
Object obj, Method method, Annotation annotation);
}
该类通过查看 getAnnotationType() 来迭代类中的方法,以确定这些方法是否修饰有特定属性;当它 找到一个方法时,就执行 validateMethod() 方法。MaxLengthValidator 类的实现见清单 7:
清单 7. MaxLengthValidator 类
public class MaxLengthValidator extends Validator {
protected void validateMethod(Object obj, Method method, Annotation annotation) {
try {
if (method.getName().startsWith("get")) {
MaxLength length = (MaxLength)annotation;
String value = (String)method.invoke(obj, new Object[0]);
if ((value != null) && (length.length() < value.length())) {
String string = method.getName() + " is too long." +
"Its length is " + value.length() +
" but should be no longer than " + length.length();
throw new ValidationException(string);
}
}
} catch (Exception e) {
throw new ValidationException(e.getMessage());
}
}
@Override
protected Class getAnnotationType() {
return MaxLength.class;
}
}
演化架构和紧急设计: 利用可重用代码,第2部分 - 捕捉惯用模式(5)
时间:2011-08-18 IBM Neal Ford
该类从 get 开始检查方法是否经过潜在验证,然后获取注释中的元数据,最后检查属性相对于所声明 长度的 length 字段值,在出现违规时抛出验证错误。
属性可以完成很高级的工作。请看下面清单 8 中的例子:
清单 8. 带惟一性验证的类
public class Region {
private String name = "";
private Country country = null;
public Region(String name, Country country) {
this.name = name;
this.country = country;
this.country.addRegion(this);
}
public void setName(String name){
this.name = name;
}
@Unique(scope = Country.class)
public String getName(){
return this.name;
}
public Country getCountry(){
return country;
}
}
要声明 Unique 属性很简单,如清单 9 所示:
清单 9. Uniq |