[SPRING] 스프링 싱글 톤 빈 필드가 채워지지 않습니다.
SPRING스프링 싱글 톤 빈 필드가 채워지지 않습니다.
보류중인 스레드 목록 (예 : 모든 것이 스레드 안전성으로 작성 됨)과 같은 일부 내부 필드와 서비스 (싱글 톤 적합)가 필요합니다. 문제는이 빈에 대해 @autowire 필드가 비어있는 것처럼 보입니다. 디버깅 프록시가 채워진 필드가있는 인스턴스 (CGLIB $ CALLBACK_X 필드가 채워진 빈에 올바르게 연결되어 있음)에 올바르게 바인딩되지만 제공되는 필드는 비어 있습니다.
다음 코드 줄은 제가 무슨 말을하고 있는지에 대한 일반적인 아이디어를 제공합니다.
@Service
public class myService{
@Autowired
private Monitor monitor;
public List getSomething(){
return monitor.getList();
}
}
@Service
public class myStatefulService{
//This field will be populated for sure by someone before getSomething() is called
private List list;
public synchronized List getSomething(){
return this.list;
}
//Called by other services that self inject this bean
public synchronized void addToList(Object o){
this.list.add(o);
}
}
내가 getList 호출하는 동안 변수 모니터 디버깅
monitor => instance of correct class
fields:
CGLIB$BOUND => true
CGLIB$CALLBACK_0.advised => proxyFactory (correct)
CGLIB$CALLBACK_1.target (reference to the correct instance of myStatefulService class)
fields:
list => [.........] (correctly populated)
CGLIB$CALLBACK_2 .....
......
......
......
list => [] (the list that would be populated is empty instead)
해결법
-
==============================
1.호기심이 있거나 진짜 문제가 있습니까? 그럼에도 불구하고 여기에 설명이 있습니다.
호기심이 있거나 진짜 문제가 있습니까? 그럼에도 불구하고 여기에 설명이 있습니다.
CGLIB를 프록시 클래스로 사용하면 Spring은 myService $ EnhancerByCGLIB와 같은 서브 클래스를 생성합니다. 이 향상된 클래스는 실제 코드 주위에 교차 관심사를 적용하는 비즈니스 메소드 전부는 아니더라도 일부를 재정의합니다.
여기에 놀라운 사실이 있습니다. 이 추가 서브 클래스는 기본 클래스의 수퍼 메소드를 호출하지 않습니다. 대신 myService의 두 번째 인스턴스를 만들고 여기에 delegate합니다. 즉, 실제 객체와 CGLIB 객체가 가리키는 (배치하는) 객체가 두 가지 있습니다.
향상된 클래스는 단지 더미 프록시입니다. 여전히 기본 클래스 (상속 된 필드)와 동일한 필드가 있지만 사용되지 않습니다. myService $ EnhancerByCGLIB 객체에서 addToList ()를 호출하면 먼저 일부 AOP 논리를 적용하고 myService (add)를 호출하여 나머지 AOP 논리를 적용시 적용합니다. myService $ EnhancerByCGLIB.list 필드는 절대 건드리지 않습니다.
Spring이 같은 클래스를 사용하고 수퍼를 통해 위임 할 수없는 이유는 무엇입니까? 단순함을 위해 다음과 같이 추측합니다. 먼저 "원시"bean을 작성한 후 사후 처리 중 AOP 프록 싱을 적용하십시오.
-
==============================
2."이 필드는 getSomething ()이 호출되기 전에 누군가에 의해 확실하게 채워질 것입니다.
"이 필드는 getSomething ()이 호출되기 전에 누군가에 의해 확실하게 채워질 것입니다.
누군가에 의해? 아니, 봄 콩 공장. 구성하지 않으면 아무 것도 채워지지 않습니다.
모든 bean이 Spring의 제어를받을 필요는 없습니다. 클라이언트가 스레드 안전 방식으로 항목을 추가하고 제거 할 수있는 목록을 갖고 싶어하는 것 같습니다. 맞으면 @Autowired 주석을 제거하고 새 List를 만들고 추가 및 제거 할 메소드를 노출하십시오.
나는 새로운 동시 수집 목록을 권하고 싶습니다.
-
==============================
3.CGLIB는 보호받는 게터를 프록시 처리합니다.
CGLIB는 보호받는 게터를 프록시 처리합니다.
그래서 당신은 가질 수 있습니다 :
@Autowired private Monitor monitor; protected Monitor getMonitor() { return monitor; } public List getSomething(){ return getMonitor().getList(); }
getMonitor ()는 모니터가 삽입 된 다른 인스턴스에서 getMonitor ()를 호출하도록 프록시 될 것입니다.
from https://stackoverflow.com/questions/11580911/spring-singleton-bean-fields-are-not-populated by cc-by-sa and MIT license
'SPRING' 카테고리의 다른 글
[SPRING] Spring Security는 런타임 중에 사용자를 로그 오프합니다. (0) | 2018.12.27 |
---|---|
[SPRING] 봄 일반 Dao 클래스 이름 (0) | 2018.12.27 |
[SPRING] 타일 2와 URI가있는 HTTP 요청에 대한 매핑이 없습니다 - Spring-MVC (0) | 2018.12.27 |
[SPRING] Spring-Jersey : 정적 컨텐츠를 반환하는 방법? (0) | 2018.12.27 |
[SPRING] 배열이나 콜렉션 매개 변수를 취하는 메소드에서 Spring Cache를 사용하기위한 전략은 무엇입니까? (0) | 2018.12.27 |