Spring-Boot 如何正确注入 javax.validation.Validator

Posted

技术标签:

【中文标题】Spring-Boot 如何正确注入 javax.validation.Validator【英文标题】:Spring-Boot How to properly inject javax.validation.Validator 【发布时间】:2014-06-29 13:12:42 【问题描述】:

在尝试使用 JSR-303 (hibernate-validator) 验证模型时,我在将 Validator 注入 Spring 应用程序 bean 时遇到问题

我的主要配置类是:

@EnableAutoConfiguration
@EnableWebMvc // <---
@EnableJpaRepositories("com.example")
@EntityScan("com.example")
public class MainConfiguration 

根据 javadocs:

/**
 * Provide a custom @link Validator instead of the one created by default.
 * The default implementation, assuming JSR-303 is on the classpath, is:
 * @link org.springframework.validation.beanvalidation.LocalValidatorFactoryBean.
 * Leave the return value as @code null to keep the default.
 */
Validator getValidator();

Hibernate-validator 在类路径中。 我正在尝试将其注入存储库:

@Repository
public class UserRepositoryImpl implements UserRepositoryCustom    

    @Autowired
    private Validator validator;

抛出异常:

 No qualifying bean of type [javax.validation.Validator] found for dependency:

更新:

对此的部分解决方法是在主配置类中定义它:

  @Bean
    public Validator validator() 

        return new org.springframework.validation.beanvalidation.LocalValidatorFactoryBean();
    

但集成测试(需要org.springframework.test.context.web.WebAppConfiguration; 注释并使用验证逻辑的测试)失败。

【问题讨论】:

您是否尝试过像docs.spring.io/spring/docs/current/spring-framework-reference/… 那样配置LocalValidatorFactoryBean 类型的bean? @geoand 是的,试过了。如果我只是在没有 WebMvc 部分的情况下启动应用程序上下文,则测试是绿色的。当我尝试将验证器注入弹簧控制器时,测试失败(无法注入验证器)。 @geoand 似乎您的解决方案有效。该问题与 Intellij Idea 内部缓存/配置有关。您能否将其发布为答案,以便我接受它 很高兴听到它成功了!我将其发布为答案:) 【参考方案1】:

您需要像这样声明LocalValidatorFactoryBean 类型的bean:

<bean id="validator"
    class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean"/>

在 XML 或

@Bean
public javax.validation.Validator localValidatorFactoryBean() 
   return new LocalValidatorFactoryBean();

在 Java 配置中。

编辑:

重要的是要了解,如果 JPA 正在使用并且由 Hibernate 支持,那么 Hibernate 将尝试自动验证您的 Bean 以及 Spring 框架。这可能导致javax.validation.ValidationException: HV000064: Unable to instantiate ConstraintValidator 的问题,因为Hibernate 不知道Spring Context,据我所知,即使使用LocalValidatorFactoryBean 也无法告诉它。这会导致验证器运行两次。一个正确,一旦失败。

为了禁用默认的 Hibernate ORM 验证,需要为 Spring 设置以下属性:

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

我更新了这个例子,因为我一遍又一遍地发现验证器没有被注入,结果证明这是我面临的问题。

This 部分 Spring 文档包含所有详细信息

【讨论】:

关于 JavaConfig 的注意事项。该方法的返回值应该是 javax.validation.Validator 。我会编辑你的答案 @SteveGreen 很高兴答案对您有所帮助! 这似乎不起作用或在使用 Spring Boot 时发生了变化。它需要 org.springframework.validation.Validator 而不是 javax Validator。 当您在主应用程序类上使用 @SpringBootApplication 时,它不应该在没有所有这些的情况下正常工作。这应该会自动为您的应用包含组件扫描和注释驱动的配置,这将配置正确的验证器。 @Amrut 我同意。查看this讨论

以上是关于Spring-Boot 如何正确注入 javax.validation.Validator的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 jpa/spring-boot 正确应用类似 PrePersist 的逻辑

spring-boot -配置文件值注入

spring-boot -配置文件值注入

javax.persistence.EntityManager SQL 注入

迁移到 JBOSS 7.4 和 Java11 后未正确注入 EJB 无状态 bean

spring boot 自定义druid数据源,如何注入配置