具有Spring失败的JSR-303约束验证器中的依赖注入失败 [英] Dependency Injection in JSR-303 Constraint Validator with Spring fails

查看:364
本文介绍了具有Spring失败的JSR-303约束验证器中的依赖注入失败的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有与此处相同的问题和此处,但找不到解决方案。

I have the same problem as here and here but couldn't find a solution yet.

所以我的示例测试项目将显示整个相关配置和代码:

So my sample test project will show the whole relevant configuration and code:

约束注释:

@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;
    [...]
}

带有@Validated的注释服务: / p>

Annotated Service with @Validated:

@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 ConstraintValidator:

JSR-303 ConstraintValidator:

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;
    }

}

注入ValidationService:

Injected ValidationService:

@Service
public class ValidationService {

    public void test(final Foo foo) {
        System.out.println(foo);
    }
}

Spring引导应用程序和配置:

Spring boot application and configuration:

@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:

relevant 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 不能自动连线?

I'm using the LocalValidatorFactoryBean with the default SpringConstraintValidatorFactory. But why the dependency injection is not working in the ConstraintValidator and the ValidationService could not be autowired?

顺便说一句,如果我不要在服务中使用 @Validated ,注入与spring或javax Validator接口相反,并手动调用 validator.validate 依赖注入将工作。但是我不想手动在每个服务中调用validate方法。

By the way if I don't use @Validated at the service, inject in opposite the spring or javax Validator interface and call manually "validator.validate" the dependency injection will work. But I don't want to call the validate method in every service manually.

非常感谢您的帮助:)

推荐答案

我在Spring Boot环境中也遇到过同样的问题,我发现Hibernate的内部实现不是配置的Spring的。当应用程序启动时,调试器在Spring的工厂中找到了一行,但是在运行时间内还有Hibernate的一个。经过一些调试,我得出结论,即 MethodValidationPostProcessor 得到了内部的。因此我配置如下:

I have fought the same problem in Spring Boot environment and I found out that Hibernate internal implementation got in instead of the configured Spring's one. When the application started, debugger caught a line with the Spring's factory but later in runtime there was Hibernate's one. After some debugging I came to the conclusion that MethodValidationPostProcessor got the internal one. Therefore I configured it as follows:

@Bean
public Validator validator() {
    return new LocalValidatorFactoryBean();
}

@Bean
public MethodValidationPostProcessor methodValidationPostProcessor() {
    MethodValidationPostProcessor methodValidationPostProcessor = new MethodValidationPostProcessor();
    methodValidationPostProcessor.setValidator(validator());
    return methodValidationPostProcessor;
}

注意验证器的设置器 - 它做了这个工作。

Note the setter for validator - it did the job.

这篇关于具有Spring失败的JSR-303约束验证器中的依赖注入失败的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆