假设有一个像这样的自定义验证注释
@Target({ElementType.TYPE, ElementType.ANNOTATION_TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Constraint(validatedBy = {ThirdPartyConstraintValidator.class})
@Documented
public @interface ThirdPartyConstraint {
String message() default "Invalid";
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
}
需要其他服务的相应Validator
public class ThirdPartyConstraintValidator implements ConstraintValidator<ThirdPartyConstraint, Pojo> {
private ThirdPartyService thirdPartyService;
@Override
public void initialize(ThirdPartyConstraint thirdPartyConstraint) {}
@Override
public boolean isValid(Pojo pojo, ConstraintValidatorContext constraintValidatorContext) {
return thirdPartyService.isValid(pojo);
}
public void setThirdPartyService(ThirdPartyService thirdPartyService) {
this.thirdPartyService = thirdPartyService;
}
}
使用Hibernate实现初始化验证上下文
ValidatorFactory factory = Validation.buildDefaultValidatorFactory();
Validator validator = factory.getValidator();
// and then some bean is validated
validator.validate(new Pojo());
在后台validate
方法调用class.newInstance()
以获取验证程序实现。因此,在ThirdPartyConstraintValidator
的情况下,永远不会注入依赖项ThirdPartyService
。
在没有任何框架的情况下使用ThirdPartyService
时,有没有办法通过setter或构造函数将ThirdPartyConstraintValidator
注入ValidationFactory
?
更新
在@matthias回答之后,我更新了我的ValidatorFactory
以初始化其中的ThirdPartyConstraintValidator
public <T extends ConstraintValidator<?, ?>> T getInstance(Class<T> aClass) {
if (ThirdPartyConstraintValidator.class.equals(aClass)) {
ThirdPartyConstraintValidator thirdPartyConstraintValidator = new ThirdPartyConstraintValidator();
thirdPartyConstraintValidator.setThirdPartyService(new ThirdPartyService());
return (T) thirdPartyConstraintValidator;
}
return null;
}
答案 0 :(得分:2)
您可以实现自定义ConstraintValidatorFactory来设置依赖关系。
请参阅BeanVal Spec或Hibernate Validator Doc
Validator v = Validation.byDefaultProvider().configure()
.constraintValidatorFactory(new MyConstraintValidatorFactory())
.buildValidatorFactory()
.getValidator();
class MyConstraintValidatorFactory implements ConstraintValidatorFactory {
public <T extends ConstraintValidator<?, ?>> T getInstance(final Class<T> arg0) {
//do your stuff to set dependencies
...
}
public void releaseInstance(final ConstraintValidator<?, ?> arg0) {
...
}
}