[SPRING] @Autowire 이상한 문제
SPRING@Autowire 이상한 문제
autowiring 할 때 나는 이상한 행동을한다.
이 코드와 비슷한 코드가 있는데 작동합니다.
@Controller
public class Class1 {
@Autowired
private Class2 object2;
...
}
@Service
@Transactional
public class Class2{
...
}
문제는 Class2가 이제 인터페이스를 구현해야하므로 Class2 만 변경 했으므로 다음과 같아야합니다.
@Controller
public class Class1 {
@Autowired
private Class2 object2;
...
}
@Service
@Transactional
public class Class2 implements IServiceReference<Class3, Long>{
...
}
public interface IServiceReference<T, PK extends Serializable> {
public T reference(PK id);
}
이 코드를 가지고 org.springframework.beans.factory.NoSuchBeanDefinitionException을 얻는다 : Class2를위한 타입의 일치하는 bean이 없다.
@Transitional 주석을 제거하거나 IServiceReference
이것이 도움이된다면 Spring 3.0.2를 사용한다.
인터페이스가 트랜잭션 방식과 호환되지 않습니까? 스프링 버그일까요?
해결법
-
==============================
1.문제는 Class1이 IServiceReference에 대한 참조가 필요하며 Class2의 구체적인 참조가 필요하지 않다는 것입니다.
문제는 Class1이 IServiceReference에 대한 참조가 필요하며 Class2의 구체적인 참조가 필요하지 않다는 것입니다.
@Controller public class Class1 { @Autowired private IServiceReference object2; ... }
그 이유는 Spring이 @Transactional이라고 표시된 클래스에 대한 동적 프록시를 생성하기 때문입니다. 따라서 Class2가 생성 될 때 Class2 유형은 아니지만 IServiceReference 유형 인 Proxy 객체로 래핑됩니다.
프록시 지원으로 Class2를 사용하는 동작을 원할 경우 CGLIB를 켜야합니다 아래를 읽으십시오 :
스프링 박사님 :
-
==============================
2.Transactional annotation은 트랜잭션 semantics를 구현하기 위해 Annotated Bean 주위에 프록시 객체를 생성하도록 Spring에 지시합니다. 생성 된 프록시는 대상 bean과 동일한 인터페이스를 구현합니다. 따라서 대상 빈에서 IServiceReference를 구현하면 생성 된 프록시도 함께 구현됩니다.
Transactional annotation은 트랜잭션 semantics를 구현하기 위해 Annotated Bean 주위에 프록시 객체를 생성하도록 Spring에 지시합니다. 생성 된 프록시는 대상 bean과 동일한 인터페이스를 구현합니다. 따라서 대상 빈에서 IServiceReference를 구현하면 생성 된 프록시도 함께 구현됩니다.
타겟 빈에 구현 된 인터페이스가 없다면, 생성 된 프록시는 대신 타겟 빈 타입의 서브 클래스가 될 것이다.
원래 예제에서 Class2는 인터페이스를 구현하지 않았기 때문에 트랜잭션 프록시는 Class2의 하위 클래스가됩니다. IServiceReference를 구현하도록 Class2를 변경하면 생성 된 프록시가 더 이상 Class2를 확장하지 않고 대신 IServiceReference를 구현합니다. 이로 인해 ClassCastException이 발생했습니다.
이 상황에 가장 적합한 방법은 Class1에서 Class2로 참조를 제거하고 대신 인터페이스를 통해 Class2와 대화하는 것입니다. Class2는 원하는만큼 많은 인터페이스를 구현할 수 있으며 프록시는 모든 인터페이스를 구현합니다.
Spring이 인터페이스에 상관없이 Spring에게 하위 클래스 프록시를 생성하도록 강요 할 수 있지만 추가적인 복잡성이 있습니다.
-
==============================
3.추가하여 강제로 프록시로 설정할 수 있습니다.
추가하여 강제로 프록시로 설정할 수 있습니다.
@Scope(proxyMode = ScopedProxyMode.TARGET_CLASS)
또한이 문서를 참조하십시오.
from https://stackoverflow.com/questions/2713033/autowire-strange-problem by cc-by-sa and MIT license
'SPRING' 카테고리의 다른 글
[SPRING] JPA와 Spring을 사용하여 목록에서 필드가있는 고유 한 행을 찾는 방법? (0) | 2019.01.22 |
---|---|
[SPRING] 한 컨트롤러 메서드에서 다른 컨트롤러 메서드로 리디렉션 (0) | 2019.01.22 |
[SPRING] Spring MVC에서 @JavaConfig가 작동하지 않는 이유는 무엇입니까? (0) | 2019.01.21 |
[SPRING] 봄 데이터 몽고 그룹 (0) | 2019.01.21 |
[SPRING] @Secured 주석은 Autoproxy로 AspectJ 모드에서 작동하지 않는다. (0) | 2019.01.21 |