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

2w2cym1i  于 5个月前  发布在  Spring
关注(0)|答案(3)|浏览(60)

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

@Component
public class ApiMockResponseValidator
    implements ConstraintValidator<MockResponse, ApiMockResponse> {

  @Autowired
  FileService fileService;

  private boolean validate(....) {
     // logic
  }

  @Override
  public boolean isValid(ApiMockResponse mockResponse, ConstraintValidatorContext context) {
    System.out.println("\n\n  --- " + fileService + " --- \n\n");  // remains null
    // validate()
  }
}

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

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


1.创建Validator bean

@Configuration
public class ValidatorConfig {

  @Bean
  @Autowired
  public Validator validator(AutowireCapableBeanFactory autowireCapableBeanFactory) {

    ValidatorFactory validatorFactory = Validation.byProvider(HibernateValidator.class).configure()
        .constraintValidatorFactory(
            new SpringConstraintValidatorFactory(autowireCapableBeanFactory))
        .buildValidatorFactory();
    Validator validator = validatorFactory.getValidator();

    return validator;
  }
}


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

@Configuration
public class ValidatorConfig {

  @Bean
  @Primary
  @Autowired
  public Validator validator(final AutowireCapableBeanFactory autowireCapableBeanFactory) {
    new SpringConstraintValidatorFactory(autowireCapableBeanFactory);
    LocalValidatorFactoryBean x = new LocalValidatorFactoryBean();
    x.setConstraintValidatorFactory(
        new SpringConstraintValidatorFactory(autowireCapableBeanFactory));
    return x;
  }

}


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

ehxuflar

ehxuflar1#

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

class FileServiceHolder {
   private static final FileServiceHolder INSTANCE = new FileServiceHolder();
   private FileService fileService;

   private FileServiceHolder() {
   }

   public static FileServiceHolder getInstance() {
      return INSTANCE;
   }

   @Autowired
   public setFileService(FileService fileService) {
      this.fileService = fileService;
   }
}

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

@Configuration
class AppConfig {
   @Bean
   FileServiceHolder fileServiceHolder() {
      return FileServiceHolder.getInstance();
   }
}


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

class Validator {
   boolean validate(....) {
      FileServiceHolder.getInstance().doStuff();
   }
}

w8ntj3qf

w8ntj3qf2#

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

// To be added in a @Configuration class:

@Bean
@Lazy
public HibernatePropertiesCustomizer hibernatePropertiesCustomizer(LocalValidatorFactoryBean validator) {
    return (Map<String, Object> hibernateProperties) -> {
        hibernateProperties.put("javax.persistence.validation.factory", validator);
    };
}

字符串

vuv7lop3

vuv7lop33#

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

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

字符串
找到解here

相关问题