복붙노트

[SPRING] @Required 주석은 JavaConfig와 어떻게 작동합니까?

SPRING

@Required 주석은 JavaConfig와 어떻게 작동합니까?

저는 Spring Framework에 익숙하지 않아 자바 구성 응용 프로그램과 결합하여 @Required 주석을 이해하는 데 문제가 있습니다.

다음은 그 예입니다.

구성 파일

@Configuration
public class AppConfig {
    @Bean
    public Movie movieA() {
        return new Movie();
    }

    @Bean
    public MovieHolder holder() {
        return new MovieHolder();
    }
}

MovieHolder.java

public class MovieHolder {

    private Movie movie;

    public Movie getMovie() {
        return movie;
    }

    @Required
    public void setMovie(Movie movie) {
        this.movie = movie;
    }
}

컨텍스트 초기화

ApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);
MovieHolder holder = (MovieHolder) context.getBean("holder");
System.out.println("movie: " + holder.getMovie());

@Required 주석의 문서를 이해하는 한, 영화가 직접 설정되거나 자동 와이어 링 (autowiring)으로 설정되지 않기 때문에 예외가 발생해야합니다. 대신 출력 동영상 : null이 있습니다.

내가 뭘 잘못하고 있죠? 아니면 @ 필수 주석을 올바르게 사용하지 않습니까?

해결법

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

    1.인스턴스화중인 bean에서 필수 특성을 설정하는 것은 사용자의 책임입니다. @Configuration으로 주석 처리 된 클래스에서 bean 정의를 처리하는 BeanPostProcessor는 ConfigurationClassPostProcessor라고 불린다. @Required 어노테이션을 처리하는 BeanPostProcessor의 기본값은 RequiredAnnotationBeanPostProcessor이며, 컨텍스트를 사용할 때 기본적으로 등록됩니다. annotation-config 및 컨텍스트 : 구성에서 구성 요소 스캔. 이 두 태그를 사용하지 않는다면 자신 만의 RequiredAnnotationBeanPostProcessor를 빈으로 등록 할 수도 있습니다.

    인스턴스화중인 bean에서 필수 특성을 설정하는 것은 사용자의 책임입니다. @Configuration으로 주석 처리 된 클래스에서 bean 정의를 처리하는 BeanPostProcessor는 ConfigurationClassPostProcessor라고 불린다. @Required 어노테이션을 처리하는 BeanPostProcessor의 기본값은 RequiredAnnotationBeanPostProcessor이며, 컨텍스트를 사용할 때 기본적으로 등록됩니다. annotation-config 및 컨텍스트 : 구성에서 구성 요소 스캔. 이 두 태그를 사용하지 않는다면 자신 만의 RequiredAnnotationBeanPostProcessor를 빈으로 등록 할 수도 있습니다.

    이제 RequiredAnnotationBeanPostProcessor의 기본 구현에는 SKIP_REQUIRED_CHECK_ATTRIBUTE라는 부울 속성을 검사하는 boolean shouldSkip (..)이라는 메소드가 있습니다. 이 속성의 값은 RequiredAnnotationBeanPostProcessor에 의한 사후 처리 중 각 bean에 대해 점검됩니다. false를 반환하면 @Required 제약 조건이 적용되고 그렇지 않으면 @Required 제약 조건이 적용됩니다.

    이제 ConfigurationClassPostProcessor는 @Configuration 클래스에서 bean 정의를 생성하는 동안이 속성의 값을 true로 설정합니다 (Bean을 정의하는 경우 필수 속성이 있는지 확인해야합니다). 따라서 @Required는 그러한 bean에 대해 적용되지 않습니다.

    옆으로, 당신은이 SKIP_REQUIRED_CHECK_ATTRIBUTE 속성이 어디서 왔고 어디에서 왔는지 생각할 수 있습니다. 빈 설정과 후 처리를 위해 내부적으로 Spring에서 사용하는 BeanDefinition의 인스턴스에 설정됩니다.

    @Required 제약 조건을 실제로 적용하려면 RequiredAnnotationBeanPostProcessor를 재정의하고 boolean shouldSkip (..) 메서드를 재정의하고 기본 RequiredAnnotationBeanPostProcessor 대신이 클래스를 등록해야합니다. 그리고 RequiredAnnotationBeanPostProcessor에 대한 문서에서 다음과 같이 말합니다 :

    또 다른 방법은 @Bean 어노테이션에서 initMethod 속성을 사용하는 것입니다. 필요한 속성이 실제로 설정되었는지 확인하기 위해 검사를 수행 할 수 있습니다. 그러나 이것은 코드 기반 구성이므로 init 메서드를 직접 호출 할 수도 있습니다.

    또한, 내 의견으로는, 당신의 RequiredAnnotationBeanPostProcessor를 사용하는 데 많은 어려움을 겪지는 않을 것입니다. 다음 문서에서 말합니다 :

    요약하면 @Required는 기본적으로 @Configuration 클래스에서 작동하지 않습니다. 모든 속성이 설정되어 있는지 확인해야하는 경우 @Bean 메서드에서 bean을 만들 때 직접 할 수 있습니다 (이러한 유효성 검사를 수행하는 일부 init 메서드를 호출하거나 필요한 속성을 직접 제공하는 것) . @Required 어노테이션을 실제로 만들어야하는 경우에는 RequiredAnnotationBeanPostProcessor를 직접 구현하여 스프링 컨텍스트에서 bean으로 등록하고 컨텍스트의 이점 인 annotation-config를 포기해야합니다.

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

    2.그냥 shouldSkip () 메서드를 재정 의하여 @Bean RequiredAnnotationBeanPostProcessor를 선언하려고했습니다.

    그냥 shouldSkip () 메서드를 재정 의하여 @Bean RequiredAnnotationBeanPostProcessor를 선언하려고했습니다.

    예, 콩을 검사하지만 필요한 모든 속성을 설정하더라도 실패합니다. 즉 항상 실패합니다. 스프링은 Java 코드에서 직접 할 때 속성을 설정했는지 여부를 알 수있는 방법이 없기 때문에 Spring이 Java Config의 @ Required Annotation을 지원할 때 실제 문제가 있다고 생각합니다. (명시 적으로 설정된 null 값을 허용해야하는 @Required 주석의 의미를 변경한다는 의미이므로 나중에 'null'필드를 검사 할 수 없습니다.)

    XML 설정을 사용하면, Spring은 속성을 설정하는 래퍼 객체를 생성하므로, 모든 구성된 'setXxx ()'작업을 추적 할 수 있습니다.

    결론 : Java @Configuration 클래스로 작성된 bean에 @Required 어노테이션을 사용하는 합리적인 방법은 없습니다. (매우 불행히도, 필자의 의견으로는 빈 클래스 작성자와 클래스 사용자가 다른 사람 일 수 있기 때문이다.)

  3. from https://stackoverflow.com/questions/16769360/how-does-required-annotation-work-with-javaconfig by cc-by-sa and MIT license