스프링이해 5 - 차이는?
좋습니다 👍
이건 **Spring Framework 내부 구조에서 가장 유명한 질문입니다.
> Spring은 순환참조(Circular Dependency)를 어떻게 해결하는가?
핵심은
3단계 캐시 (3-level cache)
입니다.
---
1️⃣ 순환참조란 무엇인가
예를 들어 이런 구조입니다.
@Service
class AService {
private final BService b;
public AService(BService b) {
this.b = b;
}
}
@Service
class BService {
private final AService a;
public BService(AService a) {
this.a = a;
}
}
구조
A → B
↑ ↓
└───┘
문제
A 생성하려면 B 필요
B 생성하려면 A 필요
그래서 일반 DI 컨테이너는
무한 루프
또는
BeanCurrentlyInCreationException
이 발생합니다.
---
2️⃣ Spring 해결 방법
Spring Framework는
3개의 캐시
를 사용합니다.
1️⃣ singletonObjects
2️⃣ earlySingletonObjects
3️⃣ singletonFactories
---
3️⃣ 1단계 캐시
singletonObjects
완전히 생성된 Bean 저장
예
AService (완성)
BService (완성)
일반 Bean 조회는 여기서 합니다.
---
4️⃣ 2단계 캐시
earlySingletonObjects
초기 생성 Bean
즉
아직 초기화 안 끝난 Bean
---
5️⃣ 3단계 캐시 (핵심)
singletonFactories
여기에는
ObjectFactory
가 들어 있습니다.
즉
Bean을 만들어 줄 팩토리
입니다.
이게 중요한 이유는
> AOP 프록시 생성 때문
입니다.
예
@Transactional
@Async
같은 Spring AOP 기능 때문입니다.
---
6️⃣ 실제 순환참조 해결 과정
예
A → B → A
---
① A 생성 시작
create A
A는 아직 완성 안 됨
그래서
singletonFactories
에 등록
A factory 저장
---
② B 생성
A가 B 필요
그래서
create B
---
③ B가 A 필요
이제 문제 발생
B → A 필요
하지만 A는 아직 생성 중
그래서 Spring이
singletonFactories
확인
---
④ early reference 생성
Spring이
ObjectFactory
로
A early object
만듭니다.
그리고
earlySingletonObjects
에 저장
---
⑤ B 생성 완료
B 완성
---
⑥ A 생성 완료
이제
A → B 주입
완료
---
7️⃣ 그림으로 보면
create A
↓
singletonFactories 저장
↓
create B
↓
B → A 필요
↓
earlySingletonObjects에서 A 제공
↓
B 완성
↓
A 완성
↓
singletonObjects 이동
---
8️⃣ 중요한 제한
이 방법은
Setter / Field Injection
에서는 가능하지만
Constructor Injection
에서는 불가능합니다.
왜냐하면
생성 전에 의존성 필요
하기 때문입니다.
그래서
constructor circular dependency
는 에러 납니다.
---
9️⃣ Spring Boot 2.6 변화
**Spring Boot 2.6부터
순환참조 기본 금지
되었습니다.
에러
circular reference detected
필요하면
spring.main.allow-circular-references=true
설정해야 합니다.
---
🔥 핵심 요약
Spring Circular Dependency 해결
│
▼
3-level cache
캐시 역할
singletonObjects 완성 Bean
earlySingletonObjects 초기 Bean
singletonFactories Bean factory
---
💡 진짜 핵심
이 구조가 필요한 이유는
AOP 프록시 때문
입니다.
그래서
Spring Framework의 Bean 생성 로직은
AbstractAutowireCapableBeanFactory
안에 구현되어 있습니다.
---
원하시면 다음도 설명해 드릴게요.
이건 Spring 내부 이해 끝판왕 3개입니다.
1️⃣ DispatcherServlet 동작 원리 (Spring MVC 90% 구조)
2️⃣ Spring AOP 프록시 생성 과정
3️⃣ Spring Boot 자동설정 직접 만드는 방법 (@Conditional)
특히 1번 DispatcherServlet 이해하면
Spring MVC 구조가 완전히 정리됩니다.
댓글
댓글 쓰기