[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.인스턴스화중인 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.그냥 shouldSkip () 메서드를 재정 의하여 @Bean RequiredAnnotationBeanPostProcessor를 선언하려고했습니다.
그냥 shouldSkip () 메서드를 재정 의하여 @Bean RequiredAnnotationBeanPostProcessor를 선언하려고했습니다.
예, 콩을 검사하지만 필요한 모든 속성을 설정하더라도 실패합니다. 즉 항상 실패합니다. 스프링은 Java 코드에서 직접 할 때 속성을 설정했는지 여부를 알 수있는 방법이 없기 때문에 Spring이 Java Config의 @ Required Annotation을 지원할 때 실제 문제가 있다고 생각합니다. (명시 적으로 설정된 null 값을 허용해야하는 @Required 주석의 의미를 변경한다는 의미이므로 나중에 'null'필드를 검사 할 수 없습니다.)
XML 설정을 사용하면, Spring은 속성을 설정하는 래퍼 객체를 생성하므로, 모든 구성된 'setXxx ()'작업을 추적 할 수 있습니다.
결론 : Java @Configuration 클래스로 작성된 bean에 @Required 어노테이션을 사용하는 합리적인 방법은 없습니다. (매우 불행히도, 필자의 의견으로는 빈 클래스 작성자와 클래스 사용자가 다른 사람 일 수 있기 때문이다.)
from https://stackoverflow.com/questions/16769360/how-does-required-annotation-work-with-javaconfig by cc-by-sa and MIT license
'SPRING' 카테고리의 다른 글
[SPRING] 유닛 테스트 결과 : HsqlException 사용자에게 권한이 없거나 객체를 찾을 수 없음 : ROWNUM (0) | 2019.02.23 |
---|---|
[SPRING] Spring 데이터 REST URI 대 엔티티 ID (0) | 2019.02.23 |
[SPRING] Spring : @Qualifier와 Property Placeholder 사용하기 (0) | 2019.02.23 |
[SPRING] Spring AOP CGLIB 프록시의 필드가 null입니다. (0) | 2019.02.23 |
[SPRING] JPA Hibernate Persistence 예외 [PersistenceUnit : default] Hibernate SessionFactory를 빌드 할 수 없다. (0) | 2019.02.23 |