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 的逻辑
javax.persistence.EntityManager SQL 注入