Spring bean (3) 순환 참조

굴착드릴·2024년 8월 14일

정의

순환 참조란 의존성이 있는 두 개 이상의 구성 요소가 서로를 직접 또는 간접적으로 참조하는 상황을 말합니다.

순환참조가 발생하는 경우 호출 시 Call stack이 터져 StackOverFlow가 발생하거나 초기화 과정에서 OutOfMemory가 발생할 수 있습니다.

예시

class A -> class B -> class A

┌──->── Bean 'a' defined in file [src/java/A.class]
|    └── Bean 'b' defined in file [src/java/B.class]
|         └── injection of dependency to bean 'a'
└─────┘

class A -> class B -> class C -> class A

┌──->── Bean 'a' defined in file [src/java/A.class]
|    └── Bean 'b' defined in file [src/java/B.class]
|         └── Bean 'c' defined in file [src/java/C.class]
|              └── injection of dependency to bean 'a'
└─────┘

Spring Framework 및 Spring Boot 버전별 순환 참조 처리 방식

Spring 버전생성자 주입세터 주입 및 필드 주입
Spring Framework 4.x 이하순환 참조 시 예외 발생순환 참조 허용
Spring Framework 5.x / Spring Boot 2.5.x 이하순환 참조 시 예외 발생순환 참조 허용
Spring Framework 5.3.x / Spring Boot 2.6.x 이상순환 참조 시 예외 발생기본적으로 순환 참조 허용 안 함 (명시적으로 허용 설정 가능)

1. Spring Framework 4.x 이하

생성자 주입

  • Spring 4.x 이하에서 생성자 주입 시 순환 참조가 발생하면 Spring이 초기화되지 않습니다.
  • 순환 참조가 발생하는 즉시 BeanCurrentlyInCreationException가 발생합니다.

세터 주입 및 필드 주입

  • Spring 4.x 이하 버전에서는 세터 주입과 필드 주입에서 순환 참조를 허용합니다.
  • Spring 컨테이너는 순환 참조를 감지하고, 빈을 초기화할 때 순환 참조를 해결하기 위해 빈의 인스턴스를 먼저 생성한 후 나중에 의존성을 주입합니다.
  • 이 방식은 기본적으로 허용되었으나, 복잡한 시나리오에서는 예기치 않은 오류를 유발할 수 있었습니다.

2. Spring Framework 5.x

생성자 주입

  • Spring 5.x에서도 생성자 주입 시 순환 참조는 허용되지 않습니다.
  • 생성자 주입으로 인해 순환 참조가 발생하면 애플리케이션 초기화 시 BeanCurrentlyInCreationException이 발생합니다.

세터 주입 및 필드 주입

  • Spring 5.x에서는 세터 주입과 필드 주입의 순환 참조를 계속해서 허용합니다.
  • 이전 버전과 마찬가지로, Spring은 빈의 인스턴스를 생성한 후 의존성을 주입하는 방식으로 순환 참조를 해결합니다.

3. Spring Boot 2.6^ 및 Spring Framework 5.3^

생성자 주입

  • 생성자 주입에서 순환 참조는 여전히 허용되지 않습니다.
  • 순환 참조가 발생하면 BeanCurrentlyInCreationException이 발생합니다.

세터 주입 및 필드 주입

  • 순환 참조를 기본적으로 허용하지 않도록 설정되었습니다.
  • 순환 참조가 발생하면 BeanCurrentlyInCreationException이 발생합니다.
  • 이전과 같은 순환 참조를 허용하려면 spring.main.allow-circular-references 프로퍼티를 true로 설정하여 순환 참조를 명시적으로 허용할 수 있습니다.
profile
두두두두..

0개의 댓글