Spring Boot 无法将依赖性注入到约束验证器实现中

2w2cym1i  于 2024-01-06  发布在  Spring
关注(0)|答案(3)|浏览(209)

我已经尝试了几种方法来注入依赖到我的ConstraintValidator实现,但没有任何工作。我已经尝试了几乎所有的stackoverflow线程。我使用Hibernate Validator来实现自定义验证。我希望FileService被注入到ApiMockResponseValidator。我分享我已经尝试过的事情。
1.简单的@Autowired注解和构造函数注入:

  1. @Component
  2. public class ApiMockResponseValidator
  3. implements ConstraintValidator<MockResponse, ApiMockResponse> {
  4. @Autowired
  5. FileService fileService;
  6. private boolean validate(....) {
  7. // logic
  8. }
  9. @Override
  10. public boolean isValid(ApiMockResponse mockResponse, ConstraintValidatorContext context) {
  11. System.out.println("\n\n --- " + fileService + " --- \n\n"); // remains null
  12. // validate()
  13. }
  14. }

字符串
我尝试过只通过构造函数注入和删除@Component,但没有任何效果,验证器没有示例化。简单的@Autowired没有注入依赖关系,构造函数自动装配给出了

  1. Caused by: javax.validation.ValidationException: HV000064: Unable to instantiate ConstraintValidator: com.lendin.ib.utils.validator.ApiMockResponseValidator.
  2. at org.hibernate.validator.internal.util.privilegedactions.NewInstance.run(NewInstance.java:44)
  3. ...
  4. ...
  5. Caused by: java.lang.NoSuchMethodException: com.test.ApiMockResponseValidator.<init>()
  6. at java.lang.Class.getConstructor0(Class.java:3082)


1.创建Validator bean

  1. @Configuration
  2. public class ValidatorConfig {
  3. @Bean
  4. @Autowired
  5. public Validator validator(AutowireCapableBeanFactory autowireCapableBeanFactory) {
  6. ValidatorFactory validatorFactory = Validation.byProvider(HibernateValidator.class).configure()
  7. .constraintValidatorFactory(
  8. new SpringConstraintValidatorFactory(autowireCapableBeanFactory))
  9. .buildValidatorFactory();
  10. Validator validator = validatorFactory.getValidator();
  11. return validator;
  12. }
  13. }


即使在这个fileService为null之后。
1.尝试创建LocalValidatorFactoryBean

  1. @Configuration
  2. public class ValidatorConfig {
  3. @Bean
  4. @Primary
  5. @Autowired
  6. public Validator validator(final AutowireCapableBeanFactory autowireCapableBeanFactory) {
  7. new SpringConstraintValidatorFactory(autowireCapableBeanFactory);
  8. LocalValidatorFactoryBean x = new LocalValidatorFactoryBean();
  9. x.setConstraintValidatorFactory(
  10. new SpringConstraintValidatorFactory(autowireCapableBeanFactory));
  11. return x;
  12. }
  13. }


这也没有帮助,fileService是null。
有什么方法可以实现注入依赖性吗?
我知道如果SpringConstraintValidatorFactory可以示例化ConstraintValidator实现,Hibernate可以直接使用它,而不是示例化实现本身,那么它就可以工作。

ehxuflar

ehxuflar1#

在ConstraintValidator示例是在Spring作用域之外创建的情况下(也许Hibernate会这样做),依赖注入不由Spring管理。
作为一种变通方法,您可以创建一个FileServiceHolder作为单例

  1. class FileServiceHolder {
  2. private static final FileServiceHolder INSTANCE = new FileServiceHolder();
  3. private FileService fileService;
  4. private FileServiceHolder() {
  5. }
  6. public static FileServiceHolder getInstance() {
  7. return INSTANCE;
  8. }
  9. @Autowired
  10. public setFileService(FileService fileService) {
  11. this.fileService = fileService;
  12. }
  13. }

字符串
Configuration类中,从该单例创建一个bean

  1. @Configuration
  2. class AppConfig {
  3. @Bean
  4. FileServiceHolder fileServiceHolder() {
  5. return FileServiceHolder.getInstance();
  6. }
  7. }


暴露相同的对象(singleton)作为bean,使Spring可以注入依赖项。这是通过setter方法setFileService完成的。
现在,在Validator类中,可以通过FileServiceHolder访问FileService

  1. class Validator {
  2. boolean validate(....) {
  3. FileServiceHolder.getInstance().doStuff();
  4. }
  5. }

展开查看全部
w8ntj3qf

w8ntj3qf2#

我在这个响应中找到了解决方案:https://stackoverflow.com/a/56557189/737587
简而言之,您需要显式地告诉Hibernate使用Spring的LocalValidatorFactoryBean。这可以通过设置javax.persistence属性来完成,这反过来可以使用HibernatePropertiesCustomizer来完成,如下所示:

  1. // To be added in a @Configuration class:
  2. @Bean
  3. @Lazy
  4. public HibernatePropertiesCustomizer hibernatePropertiesCustomizer(LocalValidatorFactoryBean validator) {
  5. return (Map<String, Object> hibernateProperties) -> {
  6. hibernateProperties.put("javax.persistence.validation.factory", validator);
  7. };
  8. }

字符串

vuv7lop3

vuv7lop33#

我也遇到了同样的问题,在application.properties上添加了这个问题就解决了:

  1. spring.jpa.properties.javax.persistence.validation.mode=none

字符串
找到解here

相关问题