【问题标题】:Not able to inject dependency into ConstraintValidator implementation无法将依赖项注入 ConstraintValidator 实现
【发布时间】:2022-07-07 20:00:02
【问题描述】:

我尝试了几种方法将依赖项注入到我的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 为空。

  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 为空。

有什么方法可以实现注入依赖?

我知道如果SpringConstraintValidatorFactory 可以实例化ConstraintValidator 实现并且Hibernate 可以只使用它而不是实例化实现本身,那么它就可以工作。

【问题讨论】:

    标签: java spring-boot bean-validation hibernate-validator customvalidator


    【解决方案1】:

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

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

    找到解决方案here

    【讨论】:

      【解决方案2】:

      如果 ConstraintValidator 实例是在 Spring 范围之外创建的(也许 Hibernate 会这样做),则依赖注入不由 Spring 管理。

      您可以做的一种解决方法是将您的验证器创建为单例

      class Validator {
         private static final Validator INSTANCE = new Validator();
         private FileService fileService;
      
         private Validator() {
         }
      
         public static Validator getInstance() {
            return INSTANCE;
         }
      
         @Autowired
         public setFileService(FileService fileService) {
            this.fileService = fileService;
         }
      }
      

      然后在 Configuration 类中从该单例创建一个 bean

      @Configuration
      class AppConfig {
         @Bean
         Validator validator() {
            return Validator.getInstance();
         }
      }
      

      将相同的对象(单例)暴露为 bean,使得 Spring 可以注入依赖项。这是通过setter方法setFileService

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2013-06-09
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-01-03
        相关资源
        最近更新 更多