2014-07-23 3 views
3

스프링 3.2.5를 사용 중이며 클래스를 BeanNameAware으로 구현하려고합니다. 이 클래스를 구현하지 않으면 내 응용 프로그램이 작동합니다. org.springframework.beans.factory.NoSuchBeanDefinitionException :에 의한BeanNameAware를 구현하면 자동 종료 됨

: 내가 그것을 같은 오류와 함께 시작하는 데 실패 구현하면 유형의 어떤 자격 콩은 [mypackage.AccountSiebelDataHolder] 의존성을 찾을 수 없습니다 :에 기대 이 종속성에 대한 후보자는 입니다. 종속성 주석 : 내가 가진

{@ org.springframework.beans.factory.annotation.Qualifier (값 = accountSiebelDataHolder), org.springframework.beans.factory.annotation.Autowired @ 는 (= TRUE 필수)} 이 같은 CLASSE :

@Transactional 
public abstract class DataHolder<T extends DbObject> implements BeanNameAware{ 

    private String beanName; 

    ... 

    @Override 
    public void setBeanName(String name) { 
     System.out.println(name); 
     this.beanName=name; 

    } 
} 

그리고 여러 클래스이 클래스 확장 :

public class AccountSiebelDataHolder extends DataHolder<AccountSiebel> { 
... 
} 

빈은 XML로 작성됩니다

<bean id="accountSiebelDataHolder" class="mypackage.AccountSiebelDataHolder"> 
... 
</bean> 

나는 모든 콩 이름을 콘솔에 표시하므로 콩이 잘 갖춰져 있음을 알고 있습니다. setBeanName() 메서드가 호출됩니다. 하지만 그 후 바로 autowiring 중에 실패합니다 (@Qualifier은 동일하거나 동일하지 않습니다)

BeanNameAware을 차일드 클래스에서 사용해 보았습니다. 동일한 결과를 제공합니다.

아마도 중요합니다.이 Dataholder 클래스는 Spring 루트 컨텍스트로 인스턴스화됩니다. 그런 다음 @MVC 문맥에 instanciated 콩 @Controller에 주입됩니다. 하지만 그것은 좋은 whithout BeanNameAware 작동합니다.

+2

프록시 생성으로 연결되는'@ Transactional'이 있습니다. 인터페이스가없는 경우 클래스 기반 프록시가 기본적으로 생성되며 인터페이스는 JDK 동적 프록시가 만들어집니다 (인터페이스 기반). ''요소에'proxy-target-class = "true"'를 추가하여 클래스 기반 프록시의 사용을 강요하십시오. –

+0

그게 해결책 이었어! 어쩌면 당신은 직접 응답 할 수있어서 나는 yoru 대답을 받아 들일 수 있습니다. – jpprade

+0

조금 더 정교한 답변을 추가했습니다 :). –

답변

3

@Transactional으로 인해 문제가 발생합니다. 트랜잭션은 AOP를 사용하고 기본적으로 Spring uses proxies을 사용하여 AOP를 적용합니다.

인터페이스 스프링이 없으면 cglib를 사용하여 클래스 기반 프록시를 만듭니다. 런타임에 동적 하위 클래스가 만들어지면이 하위 클래스는 여전히 DataHolder 인스턴스입니다.

인터페이스를 추가하면 인터페이스 인 JDK Dynamic 프록시가 생성됩니다. 런타임시 객체의 모든 인터페이스를 프록시로 구현하는 동적 클래스가 작성됩니다. 이로 인해 클래스는 BeanNameAware 인스턴스이고 더 이상 인스턴스가 DataHolder이 아닙니다.

이 문제를 해결하려면 트랜잭션 지원에서 항상 클래스 기반 프록시를 사용하십시오. 이 경우 proxy-target-class 속성은 <tx:annoation-driven />에서 true으로 설정됩니다.

<tx:annotation-driven proxy-target-class="true" />