스프링 소스 솔루션 순환 종속성을 해결하기 위해

1. 순환 종속성은 무엇인가?

순환 종속성 실제로 두 서로 잡아 결국 폐 루프를 형성하기 위해 빈의 둘 이상의 인 원형 기준이다. 예를 들어, A가 B에 의존, B는 코드 A를 직접 우리에 따라 달라집니다

ServiceB에 따라 클래스 ServiceA을 만든 다음 차례로 ServiceB는 ServiceA에 따라 달라집니다

@Component
public class ServiceA {

    @Autowired
    private  ServiceB serviceb;
@Component
public class ServiceB {

    @Autowired
    private  ServiceA servicea;

2. 싱글 봄 객체의 초기화는 세 단계로 나누어 져 있습니다 :

  1. createBeanInstance는 : 인스턴스, 사실, 객체를 인스턴스화하는 객체의 생성자 메서드를 호출

  2. 채우기 속성은,이 단계는 다중 콩 충전의 특성에 주로 의존

  3. InitializingBean 표시 호 구현 같은 오버 INIT-방법의 구성 파일 인터페이스 afterPropertiesSet 법 메소드 호출.

  4.  실시 초기화 상술 한 빈에서 알 수도 : 순환 종속성 즉 생성자 의존성 사이클주기 종속 필드 처음 두 단계에서 주로 발생한다. 우리는 존재해야 Cache 개체를 생각하기 쉽습니다, 그래서 전체 수명주기 내에서 스프링 컨테이너에서, 하나의 경우에, 초기화 과정에서 시작하고, 단 하나의 객체한다 순환 참조를 해결 봄의 하나의 사건을 해결하기 위해 필요 그래서 세 레벨의 캐시를 사용하여 순환 종속성.

        이것은 다음과 같이 내부적으로, singletonFactories 및 earlySingletonObjects는이 두 속성은 클래스 DefaultSingletonBeanRegistry에 정의되어 사용되는 정의 된 두 개의 내부 스프링의 특성을 포함합니다 :

여기서 우리는 빈의 하나의 예를 만드는 단계 스프링 그것을보고

첫 번째 단계는 다음 ServiceA 만드는

진입의 org.springframework.beans.factory.support.AbstractBeanFactory #의 getBean 방법

가 처음 ServiceA에서 생성되기 때문에, singletonFactories 및 earlySingletonObjects 및 singletonFactories이 없습니다. 그래서 널 (null)을 반환했습니다.

그런 다음 serviceA BeanWrapper를 생성 방지 세트에 의해이 시간 org.springframework.beans.factory.support.DefaultSingletonBeanRegistry # addSingletonFactory를 호출 우리 singletonFactories이 serviceA

우리 ServiceB가로드되지 않은이 시점에서이 ServiceA 속성 ServiceB은 다음 ServiceA 필요에 ServiceB 다음 ServiceB을 만들 수있는 방법의 봄을 불러 갔기 때문에 그런 속성이, populateBean의 ServiceA을 가득 전화

우리가 다음 인해 ServiceA을 따라 차례로 ServiceB에, ServiceB 속성을 채우기 위해 계속 그렇다면, 이미 singletonFactories 안쪽이 시간 ServiceA 때문에 ServiceA을 만들 이동 한 다음 우리가 (이 시간에 serviceB 속성이 null이다) 하나 ServiceA를 반환, 및 ServiceA는 earlySingletonObjects 첨가 singletonFactories에서 내부로부터 제거 하였다.

무슨 소용이이 일을합니까? 우리는 "필드 A 또는 B 개체의 인스턴스에 의존 세터뿐만 아니라, 상기 오브젝트의 인스턴스에 의존 세터 필드 B 또는 A"이 순환 종속성의 경우를 살펴 보자. 첫 번째 단계는 첫 번째 초기화를 완료하고, 초기화의 두 번째 단계는 객체 B 자신이 의존 발견하는 경우 singletonFactories 사전에 자신의 노출, 이번에는 (B) GET하려고, B는 만들 발견되지 않았다 그래서 프로 시저를 만들 가서, B는 첫 번째 단계 (초기화 A는 완전히 초기화되지 않았기 때문에, 확실히) 그래서 (A), 캐시 singletonObjects을 시도 얻을려고하는의 대상에 자신이 의존 발견, 보조 캐시 earlySingletonObjects 시도 B는 (더 좋은 괜찮보다가 완전히 초기화되지 않았지만, 그러나) ObjectFactory.getObject하여 객체 a를 얻을 수 있도록,은 A ObjectFactory를 때문에 그의 초기 노출, 세 개의 캐시 singletonFactories을 시도하지 (하지 않았다), B 걸릴 다음 완전히 초기화 초기화 단계, 2, 3의 성공적인 완료에 대한 주제에 캐시 singletonObjects에 자신을 넣어 것입니다. A B를 얻을 때문에이 시간에 반환은, 현재는 A 객체 B가 초기화 단계 2와 3의 결승전도 완료 초기화의 성공적인 완료를 얻기 위해, 캐시 singletonObjects은 더욱 다행스럽게도에 가서, 개체에 대한 참조는 A-B는 이제 라이브 주제는 초기화를 완료 누르고 있습니다.

확실히 봄이 해결할 수없는 이유를 알고, 때이 원리를 알고, 어떤 문제의 "개체 A의 인스턴스에 따라 건설 객체 B의 종속 인스턴스의 방법,하지만 B의 생성자입니다!" singletonFactories 세 레벨 캐시를 추가 전제 생성자를 수행하기 때문에, 순환 종속성 생성자는 해결 될 수 없다.

 

참조 : https://blog.csdn.net/u010853261/article/details/77940767

게시 55 개 원래 기사 · 원 찬양 31 ·은 80000 +를 볼

추천

출처blog.csdn.net/zengfanwei1990/article/details/105336778