[SPRING] Spring의 "자동 프록시를 사용할 수 없음"원인 추적
SPRINGSpring의 "자동 프록시를 사용할 수 없음"원인 추적
Spring의 자동 프록시 기능을 사용하기 시작하면 다음과 같이 문서화 된대로이 동작을 자주 접하게됩니다.
즉, 내 자신의 BeanPostProcessor를 작성하고 해당 클래스가 컨텍스트에서 다른 Bean을 직접 참조하면 해당 참조 된 Bean은 자동 프록시에 적합하지 않으며 해당 효과에 메시지가 기록됩니다.
내 문제는 "직접 참조"가 실제로 애플리케이션 컨텍스트에서 빈의 절반을 차지하는 전이 종속성 체인 일 수 있기 때문에 직접 참조가 어디에 있는지 추적하는 것이 매우 어려울 수 있다는 것입니다. 모든 Spring은 단일 정보 메시지를 제공합니다. 콩이이 참조 웹에 걸렸을 때 알려주지 않고서는별로 도움이되지 않습니다.
내가 개발중인 BeanPostProcessor는 다른 bean에 대한 직접적인 참조를 가지고 있지만 매우 제한된 참조 세트입니다. 그럼에도 불구하고 내 컨텍스트의 거의 모든 bean은 로그 메시지에 따라 자동 프록시가 적용되지 않도록 제외되지만 그 종속성이 어디에서 발생하는지 볼 수 없습니다.
누구든지 이것을 추적하는 더 좋은 방법을 찾았습니까?
해결법
-
==============================
1.이 제조법을 따르십시오 :
이 제조법을 따르십시오 :
배경
이 상황을 상상해보십시오.
public class FooPP implements BeanPostProcessor { @Autowire private Config config; }
Spring이 config를 생성해야 할 때 (FooPP의 의존성이기 때문에), 문제가있다 : 계약서에 모든 BeanPostProcessor가 생성되는 모든 bean에 적용되어야한다고한다. 그러나 Spring이 config를 필요로 할 때, 서비스 준비가되어 있지 않은 적어도 하나의 PP (즉, FooPP)가있다!
@Configuration 클래스를 사용하여이 Bean을 정의 할 때 이것은 더 나빠집니다.
@Configuration public class BadSpringConfig { @Lazy @Bean public Config config() { return new Config(); } @Lazy @Bean public FooPP fooPP() { return new FooPP(); } }
모든 구성 클래스는 bean입니다. 그것은 BadSpringConfig에서 빈 팩토리를 만드는 것을 의미합니다. Spring은 포스트 프로세서 fooPP를 적용해야하지만 그렇게하기 위해서는 먼저 bean factory가 필요합니다 ...
이 예에서 순환 종속성 중 하나를 제거 할 수 있습니다. FooPP가 BeanFactoryAware를 구현하여 Spring이 포스트 프로세서에 BeanFactory를 삽입하도록 만들 수 있습니다. 그렇게하면 자동 와이어 링이 필요하지 않습니다.
코드의 뒷부분에서 lazily가 bean을 요청할 수 있습니다.
private LazyInit<Config> helper = new LazyInit<Config>() { @Override protected InjectionHelper computeValue() { return beanFactory.getBean( Config.class ); } }; @Override public Object postProcessBeforeInitialization( Object bean, String beanName ) throws BeansException { String value = helper.get().getConfig(...); }
(LazyInit 소스)
빈 팩토리와 포스트 프로세서 사이의주기를 깨기 위해서는 포스트 프로세서를 XML 설정 파일로 설정해야한다. Spring은 그것을 읽을 수 있고 혼동하지 않고 모든 구조를 만들 수 있습니다.
-
==============================
2.이 질문에 일부 종결을하기 위해, 초기화되지 않은 객체 그래프의 붕괴는 BeanPostProcessor가 @Autowired를 사용하여 종속성을 얻음으로써 야기되었고, Autowire 메커니즘은 BeanPostProcessor가 가질 수있는 기회를 갖기 전에 다른 모든 Bean 정의를 효과적으로 초기화 시켰습니다. 그 문제에 대해서. 솔루션은 BPP에 자동 와이어 링을 사용하지 않는 것입니다.
이 질문에 일부 종결을하기 위해, 초기화되지 않은 객체 그래프의 붕괴는 BeanPostProcessor가 @Autowired를 사용하여 종속성을 얻음으로써 야기되었고, Autowire 메커니즘은 BeanPostProcessor가 가질 수있는 기회를 갖기 전에 다른 모든 Bean 정의를 효과적으로 초기화 시켰습니다. 그 문제에 대해서. 솔루션은 BPP에 자동 와이어 링을 사용하지 않는 것입니다.
-
==============================
3.어떤 도움이 필요한지 확실하지 않지만 Eclipse Spring IDE 그래프 뷰는 빈 참조를 정렬하는 데 도움이 될 것 같습니다.
어떤 도움이 필요한지 확실하지 않지만 Eclipse Spring IDE 그래프 뷰는 빈 참조를 정렬하는 데 도움이 될 것 같습니다.
from https://stackoverflow.com/questions/1201726/tracking-down-cause-of-springs-not-eligible-for-auto-proxying by cc-by-sa and MIT license
'SPRING' 카테고리의 다른 글
[SPRING] Mockito : 실제 개체를 전용 @Autowired 필드로 주입합니다. (0) | 2018.12.16 |
---|---|
[SPRING] property-placeholder에 의해 생성 된 속성에 대한 프로그래밍 방식의 액세스 (0) | 2018.12.16 |
[SPRING] 내 웹 애플리케이션에 (스프링 보안을 통해) 로그인 한 모든 사용자 목록을 어떻게 표시 할 수 있습니까? (0) | 2018.12.16 |
[SPRING] 스프링 기반 SockJS / STOMP 웹 소켓이있는 JSON 웹 토큰 (JWT) (0) | 2018.12.16 |
[SPRING] 클러스터 환경에서 실행되는 Spring Scheduled Task (0) | 2018.12.16 |