복붙노트

[SPRING] 스프링이있는 JSR-303 제약 검사기의 종속성 삽입 실패

SPRING

스프링이있는 JSR-303 제약 검사기의 종속성 삽입 실패

나는 여기와 여기 같은 문제가 있지만 아직 해결책을 찾을 수 없습니다.

그래서 내 샘플 테스트 프로젝트는 모든 관련 구성과 코드를 보여줄 것입니다 :

구속 조건 주석 :

@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 주석 서비스 :

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

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 :

@Service
public class ValidationService {

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

스프링 부트 응용 프로그램 및 구성 :

@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();
    }

}

관련 커뮤니티 :

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

기본 SpringConstraintValidatorFactory와 함께 LocalValidatorFactoryBean을 사용하고 있습니다. 하지만 왜 ConstraintValidator에서 종속성 삽입이 작동하지 않고 ValidationService를 자동 실행 할 수 없습니까?

그런데 서비스에서 @Validated를 사용하지 않으면 스프링 또는 javax Validator 인터페이스 반대쪽에 주입하고 수동으로 "validator.validate"를 호출하여 종속성 삽입이 작동합니다. 하지만 모든 서비스에서 validate 메소드를 수동으로 호출하고 싶지는 않습니다.

많은 도움을 주셔서 감사합니다 :)

해결법

  1. ==============================

    1.나는 Spring 부트 환경에서 같은 문제를 겪었고 Hibernate 내부 구현이 설정된 Spring의 구현 대신에 들어 있다는 것을 알았다. 응용 프로그램이 시작되면 디버거는 Spring의 팩토리를 사용하여 행을 잡았지만 나중에는 런타임에 최대 절전 모드의 것이있었습니다. 디버깅이 끝나면 MethodValidationPostProcessor에 내부 오류가 있다는 결론을 내 렸습니다. 따라서 다음과 같이 구성했습니다.

    나는 Spring 부트 환경에서 같은 문제를 겪었고 Hibernate 내부 구현이 설정된 Spring의 구현 대신에 들어 있다는 것을 알았다. 응용 프로그램이 시작되면 디버거는 Spring의 팩토리를 사용하여 행을 잡았지만 나중에는 런타임에 최대 절전 모드의 것이있었습니다. 디버깅이 끝나면 MethodValidationPostProcessor에 내부 오류가 있다는 결론을 내 렸습니다. 따라서 다음과 같이 구성했습니다.

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

    유효성 검사기에 대한 설정자를 확인하십시오.

  2. ==============================

    2.나는 같은 문제가 있었다. Hibernate가 Spring 대신에 validator를 찾고 적용하기 때문에 문제가 발생한다. 따라서 Hibernate를 설정할 때 검증 모드를 NONE으로 설정해야한다.

    나는 같은 문제가 있었다. Hibernate가 Spring 대신에 validator를 찾고 적용하기 때문에 문제가 발생한다. 따라서 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...
    

    LocalValidatorFactoryBean을 구성했다면 Spring은 @Component로 주석 처리 된 모든 유효성 검사기를 선택하여 autowire합니다.

  3. from https://stackoverflow.com/questions/27526620/dependency-injection-in-jsr-303-constraint-validator-with-spring-fails by cc-by-sa and MIT license