2013-09-25 4 views
2

autowire 된 모든 bean이 프록시에 의해 autowired되지 않는 이유를 찾을 수 없다. @Transactional 주석이 작동하지 않고 Eclipse에서 디버깅하는 동안 autowired 구성 요소를 확인했기 때문에 나는 알고 있습니다. 물론 모든 구성 요소는 일부 인터페이스를 구현하며 인터페이스와 관련하여 @Autowired 주석을 사용합니다. 나는 AOP의 한 구성을 가지고 :왜 autowire에 프록시가 사용되지 않는가?

<tx:annotation-driven transaction-manager="transactionManager" /> 

나 최대 절전 모드, 스프링 MVC, 스프링 webflow, 스프링 보안 및 스프링 데이터 JPA를 사용합니다. org.springframework.data.repository.CrudRepository을 확장하는 인터페이스는 프록시에 의해 자동 연결됩니다. 하지만 내 구성 요소가 아닙니다. 어디 선가하는 MyInterface를 autowire하기 경우

@Service 
public class MyClass implements MyInterface { 
@Autowired 
MyCrudReposiotry reposiotry; 
.... 
} 

: 예를 들어 내가 MyInterface를 구현하는 클래스 MyClass

@Autowired 
MyInterface mi; 

다음 mi 그냥 MyClass 객체를 참조하고, 저장소는 프록시 org.springframework.aop.framework.JdkDynamicAopProxy에에 refrence입니다. 매우 흥미로운 것은 테스트에서 mi이 프록시를 참조한다는 것입니다. 내 테스트의 컨텍스트에는 웹 흐름과 mvc 구성이 포함되어 있지 않습니다.

아마도 간접적 인 구성이 있습니다. 프록시로 autowiring을 끌 수있는 것은 무엇입니까?

답변

6

내 생각에 동일한 구성 요소를 두 번 스캔하고 있습니다. 루트 컨텍스트 (ContextLoaderListener의 경우)와 DispatcherServlet의 컨텍스트 (있는 경우)가있을 ​​수 있습니다. 두 클래스 모두 동일한 클래스를 검색하여 중복 된 (그리고 프록시 된 인스턴스 하나와 프록시되지 않은 인스턴스 한 개) 경우.

+0

감사합니다. 도움을 주셔서 대단히 감사합니다. 문제는''입니다. 나는 '만 가지고 있었지만 DispatcherServlet 컨텍스트에서만. 이제는 DispatcherServlet 컨텍스트의 컨트롤러 패키지에 대한 및 루트 컨텍스트의 내 서비스 패키지에 대한 두 번째''항목이 있습니다. – Mariusz

4

프록시 및 자동 배선은 서로 독립적입니다. @AutoWired을 사용하면 필요한 인터페이스를 구현하는 다른 bean을 찾아서 주입합니다. 발견 된 bean 인스턴스는 일반적인 오브젝트 또는 프록시 일 수 있습니다. Autowired에는 문제가되지 않습니다.

프록시는 특정 빈에 대해 봄에 자동으로 생성됩니다. 이 상황이 발생하는 한 가지 예를 들자면 @Transactional을 사용할 때입니다. 스프링 컨테이너가 @Transactional 어노테이션을 가진 빈을 인스턴스화하면 객체는 프록시로 래핑된다. 실제 객체는 컨텍스트에서 프록시로 대체됩니다. 이것은 스프링이 메소드에 대한 호출을 인터셉트하고 메소드 호출 전후에 begin/commit 트랜잭션 호출을 추가 할 수 있도록하기 위해 수행됩니다. 이것은 spring-aop 모듈에 의해 구현됩니다. AOP (@Transactional, @Secured)를 사용하는 모든 기능은 프록시 생성을 초래합니다.

프록시가 사용되는 다른 경우는 즉시 구현을 만드는 것입니다. CRUDRepository의 경우 인터페이스 만 구현하면됩니다. 이 구현은 동일한 프록시 인프라를 사용하여 즉석에서 만들어집니다.

+0

감사합니다. – Mariusz