我和这里有同样的问题,但还没有找到解决方案。
所以我的示例测试项目将显示整个相关配置和代码:
约束注释:
@Target({ ElementType.METHOD, ElementType.FIELD })
@Retention(RetentionPolicy.RUNTIME)
@Constraint(validatedBy = FooValidator.class)
public @interface FooValid {
String message();
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
}
注释PoJo:
public class Foo {
@FooValid(message = "Test failed")
private Integer test;
[...]
}
带注释的服务@验证:
@Service
@Validated
public class FooService {
private final Test test;
@Autowired
public FooService(final Test test) {
this.test = test;
}
public void foo(@Valid final Foo foo) {
this.test.test(foo);
}
}
JSR-303约束验证器:
public class FooValidator implements ConstraintValidator<FooValid, Integer> {
@Autowired
private ValidationService validationService;
@Override
public void initialize(final FooValid constraintAnnotation) {
// TODO Auto-generated method stub
}
@Override
public boolean isValid(final Integer value, final ConstraintValidatorContext context) {
// this.validationService is always NULL!
Assert.notNull(this.validationService, "the validationService must not be null");
return false;
}
}
注入验证服务:
@Service
public class ValidationService {
public void test(final Foo foo) {
System.out.println(foo);
}
}
Spring Boot应用及配置:
@Configuration
@ComponentScan
@EnableAutoConfiguration
public class Application {
public static void main(final String[] args) {
final ConfigurableApplicationContext context = SpringApplication.run(Application.class, args);
final FooService service = context.getBean(FooService.class);
service.foo(new Foo());
}
@Bean
public static LocalValidatorFactoryBean validatorFactory() {
return new LocalValidatorFactoryBean();
}
@Bean
public static MethodValidationPostProcessor validationPostProcessor() {
return new MethodValidationPostProcessor();
}
}
相关maven pom:
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.1.9.RELEASE</version>
<relativePath/>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-validator</artifactId>
</dependency>
</dependencies>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<start-class>demo.Application</start-class>
<java.version>1.7</java.version>
</properties>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
我将LocalValidatorFactoryBean与默认的SpringConstraintValidatorFactory一起使用。但是为什么依赖注入在ConstraintValidator中不起作用并且ValidationService无法自动安装?
顺便说一句,如果我在服务中不使用@Val的方法,注入到Spring或javax Validator接口的对面,并手动调用“validator. validator”,则依赖注入将起作用。但我不想手动调用每个服务中的验证方法。
非常感谢帮助:)
我在Spring Boot环境中遇到了同样的问题,我发现Hibernate内部实现代替了配置的Spring的实现。当应用程序启动时,调试器捕获了Spring工厂的一条线,但后来在运行时出现了Hibernate的工厂。经过一些调试,我得出了方法验证后处理器得到了内部的结论。因此我如下配置:
@Bean
public Validator validator() {
return new LocalValidatorFactoryBean();
}
@Bean
public MethodValidationPostProcessor methodValidationPostProcessor(Validator validator) {
MethodValidationPostProcessor methodValidationPostProcessor = new MethodValidationPostProcessor();
methodValidationPostProcessor.setValidator(validator);
return methodValidationPostProcessor;
}
注意验证器的setter-它完成了这项工作。
我也有同样的问题。出现问题是因为Hibernate正在查找和应用验证器而不是Spring。所以在配置Hibernate时,您需要将验证模式设置为NONE
:
@Bean(name="entityManagerFactory")
public LocalContainerEntityManagerFactoryBean
localContainerEntityManagerFactoryBean(DataSource dataSource) {
LocalContainerEntityManagerFactoryBean lcemfb =
new LocalContainerEntityManagerFactoryBean();
lcemfb.setDataSource(dataSource);
lcemfb.setJpaVendorAdapter(new HibernateJpaVendorAdapter());
lcemfb.setValidationMode(ValidationMode.NONE);
// Continue configuration...
如果您已经配置了LocalValidationFactoryBean Spring将获取任何带有@Component
注释的验证器并自动装配它们。
这对我很有用。我必须使用@Inject标签。
public class FooValidator implements ConstraintValidator<FooValid, Integer> {
private ValidationService validationService;
@Inject
public FooValidator(ValidationService validationService){
this.validationService = validationService;
}
@Override
public void initialize(final FooValid constraintAnnotation) {
// TODO Auto-generated method stub
}
@Override
public boolean isValid(final Integer value, final ConstraintValidatorContext context) {
// this.validationService is always NULL!
Assert.notNull(this.validationService, "the validationService must not be null");
return false;
}
}