我正在使用 Bean 验证。我有一个自定义验证器@MyValidator
需要使用注入的 Spring 管理的 DAO 对象查找值。我怎样才能访问这个? Spring 没有将 DAO 注入到我的“MyValidator”对象中。
@Component
public class CodeListValidator implements ConstraintValidator<CodeList, String> {
@Autowired
private ICodeListCommonService codeListCommonService;
private CodeListEnum codeListID;
@Override
public void initialize(CodeList constraintAnnotation) {
this.codeListID = constraintAnnotation.value();
}
@Override
public boolean isValid(String value, ConstraintValidatorContext context) {
return codeListCommonService.doesCodeEntityExistForCodeList(codeListID.getDbCodeListId(), value, ProviderConstants.CODE_LIST_STATUS_ACTIVE);
}
}
“codeListCommonService”为空。这是因为 Spring 没有创建该类 - 但我怎样才能让它与 Spring AoP 一起工作?
该验证器的使用如下所示:
ValidatorFactory factory = Validation.buildDefaultValidatorFactory();
Validator validator = factory.getValidator();
MyObject validateMe = new MyObject();
Set<ConstraintViolation<MyObject>> constraintViolations = validator.validate(validateMe);
对于我的对象:
public class MyObject {
@Size(max = 1)
@CodeList(CodeListEnum.CARTYPE)
public String carType;
}
因此,当验证器运行时,它会处理注释...我只需要将一个服务注入到我制作的 CodeListValidator 中,它就可以进行数据库查找,以根据“有效汽车类型值”的数据库列表验证该值。
编辑:解决方案:
尝试过创建一个 Spring 感知工厂的想法——与现有代码的集成过多。
看起来最好的解决方案(并且在这里有效)是创建一个 Spring 服务,将 ApplicationContext 存储在静态方法中,以便“非 Spring 管理的”bean 可以访问它们。
所以一个新服务:
@Service
public class SpringApplicationContextService implements ISpringApplicationContextService, ApplicationContextAware {
private static ApplicationContext applicationContext;
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
this.applicationContext = applicationContext;
}
public static ApplicationContext getApplicationContext() {
return applicationContext;
}
}
然后任何验证器或非 Spring bean 都可以通过以下方式获取 Spring bean:
public class CodeListValidator implements ConstraintValidator<CodeList, String> {
@Autowired
private ICodeListCommonService codeListCommonService;
private CodeListEnum codeListID;
@Override
public void initialize(CodeList constraintAnnotation) {
this.codeListID = constraintAnnotation.value();
}
@Override
public boolean isValid(String value, ConstraintValidatorContext context) {
ICodeListCommonService codeListCommonService = SpringApplicationContextService.getApplicationContext().getBean(ICodeListCommonService.class);
return codeListCommonService.doesCodeEntityExistForCodeList(codeListID.getDbCodeListId(), value, ProviderConstants.CODE_LIST_STATUS_ACTIVE);
}
}
当然,这一切的原因(在这个应用程序中使用了数十次):
@CodeList(CodeListEnum.EMAIL_OPT_OUT_FLAG)
public String emailOptOutFlag;
@CodeList(CodeListEnum.CLEARING_HOUSE)
public String clearingHouse;