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

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

问题描述

我和这里有同样的问题这里,但还没有找到解决方案.

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 的注解服务:

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 约束验证器:

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

}

注入的验证服务:

@Service
public class ValidationService {

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

Spring Boot 应用和配置:

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(Validator validator) {
    MethodValidationPostProcessor methodValidationPostProcessor = new MethodValidationPostProcessor();
    methodValidationPostProcessor.setValidator(validator);
    return methodValidationPostProcessor;
}

注意验证器的设置器 - 它完成了工作.

Note the setter for validator - it did the job.

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

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