让我们考虑以下示例,我正在通过新的注释类型创建自定义bean验证约束:
@Target( { METHOD, FIELD, ANNOTATION_TYPE })
@Retention(RUNTIME)
@Constraint(validatedBy = MyAbstractOrInterfaceValidator.class)
@Documented
public @interface MyAnnotation {
String message() default "{}";
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
SomeClass value();
}
我的问题是:can MyBastractOrInterfaceValidator
类可以是抽象类还是接口?如何控制该接口或抽象类的哪个实现用于验证注释所在的元素?
答案 0 :(得分:0)
请参阅http://docs.oracle.com/javaee/7/api/javax/validation/Constraint.html
首先,请注意validatedBy
是Class<? extends ConstraintValidator<?,?>>[]
,这是一个数组,而不是一个类。
其次,没有理由使用接口或抽象类,因为该类需要实例化。
但是,如果您想在运行时更改验证器的实现,请尝试使用:
public class MyValidator implements ConstraintValidator<MyAnnotation, String> {
//store the Class information in a static variable
private static Class<? extends ConstraintValidator<MyAnnotation, String>> implementationClass = MyValidatorOne.class;
//and change it by an accessor
public static void setImplementationClass(Class<? extends ConstraintValidator<MyAnnotation, String>> implClass) {
this.implementationClass = implClass;
}
//this delegate will do all the job
private final ConstraintValidator<MyAnnotation, String> implementation;
public MyValidator() {
implementation = implementationClass.newInstance();
}
@Override
void initialize(MyAnnotation constraintAnnotation) {
implementation.initialize(constraintAnnotation);
}
@Override
boolean isValid(T value, ConstraintValidatorContext context) {
return implementation.isValid(value, context);
}
}
代码中的某个地方:
MyValidator.setImplementationClass(MyValidatorTwo.class);
但是有一个问题。很可能每个验证器的一个实例在运行时为单个类创建一次 - 在该类对象的第一次验证调用上。实施变更只有在此之前完成才会生效。
其他方法是将implementationClass
值存储在外部类中,例如java.util.Properties或选择具有某些优先级的可用实现的类。
答案 1 :(得分:0)
不,那是不可能的。如果要从公共约束定义中隐藏验证器实现,可以使用以下选项:
validation.xml
。