2012-07-18 2 views
6

클래스 유형을 통해 bean을 검색해야합니다. 빈이 프록시 (일부 메소드는 @ 트랜잭션)로 랩핑되었을 때 - ApplicatoinContext가 빈을 찾지 못한다. 인터페이스를 통해 그들을 살펴보면 작동하지만이 경우에는 구체적인 클래스 유형으로 작업하고 있습니다. 콩이 내가 찾고있는 유형이라는 것을 알고 있지만 getBean() 메소드는 실패합니다.Spring ApplicationContext.getBean (Class c)가 프록시 클래스에서 작동하지 않습니다.

Spring의 AbstractBeanFactory 코드에서 문제를 디버그 (및 수정) 할 수 있습니다. 문제는 내가 요청하는 유형에 대해 beanInstance의 유형을 확인하지만 beanInstance.getClass()는 Proxy입니다. AbstractBeanFactory는이를 보완하고 유형을 프록시의 대상 클래스와 비교해야합니다.

나는 이것에 대한 해결책을 가지고 있지만 특히 패치 된 버전의 스프링을 사용하고 싶지는 않습니다.이 작업을 수행하기 위해 구성 할 수있는 것이 있거나 이것이 정말로 버그입니까?

답변

11

스프링이 AOP를 구현하는 두 가지 주요 방법 (예 : @Transactional 지원)은 프록시 인터페이스 또는 CGLIB를 사용하는 것입니다.

클래스가 인터페이스를 구현하는 경우 (기본값) Spring은 모든 인터페이스를 구현하는 프록시를 만듭니다. 이제부터는 해당 인터페이스를 통해 bean과 만 작업 할 수 있습니다. 당신의 반은 그들 안에 깊숙히 묻혀 있습니다.

대신 를 통해 대상 클래스를 프록시 사용하는 경우 :

<aop:config proxy-target-class="true"> 

봄 대신 (obvoiusly 여전히 모든 인터페이스를 구현) 서브 클래스를 생성합니다. 이렇게하면 문제가 해결됩니다. 그러나 반환 된 객체는 실제로 클래스가 아니라 원래 객체로 래핑하고 위임 한 동적으로 생성 된 하위 클래스라는 점을 기억하십시오. 이것은 대부분의 경우에 문제가되어서는 안됩니다.

그리고 물론 이것은 버그가 아니지만 잘 알려진 동작이며 아니요, 스프링을 패치 할 필요가 없습니다.

+0

설명을 주셔서 감사합니다. 인터페이스를 통해 빈을 검색 할 수있었습니다. 나는 그것을 사용하는 것에 대해 생각했지만 문제는 필자의 상황에서 구체적인 클래스를 참조해야한다는 것이다. (구체적인 클래스는 내가 의존하고있는 또 다른 인터페이스를 구현한다.) 나는 오늘 GCLIB 옵션을 사용하여 그 문제를 해결하겠다고 결론을 내렸다. 왜 그걸 사용하고 싶지 않겠습니까? 프록시 클래스 사용에 관해서는,이 기능은 '버그'나 '버그'와 같은 냄새가납니다. –

+0

@AlexWorden : 클래스가 여러 인터페이스를 구현하는 경우 그 중 하나를 사용하여 Bean을 가져올 수 있습니다. CGLIB의 단점 중 하나는 ... CGLIB (외부 라이브러리)를 사용해야한다는 것입니다. 글쎄, 그것은 버그도 아니고 기능도 아닙니다. 스프링은 AOP를 어떻게 든 구현해야하며, 가장 일반적인 두 가지 기능입니다. 또한 CGLIB에는 클래스 대신 두 인스턴스를 만드는 것과 같은 부작용이 있습니다. 댓글이 2 개 많습니다. –

1
<context:component-scan base-package="<Your base package name goes here>" /> 
<aop:aspectj-autoproxy /> 
<aop:config proxy-target-class="true"/> 

이 applicationContext.xml이 이러한 세 줄을 쓰기도 참조 나를 위해 일했다.