빈 등록 순환 참조 문제
## 예시 1: 두 Bean이 서로를 주입하는 경우 (A → B, B → A)
가장 대표적인 순환 참조 예시입니다. ServiceA
는 ServiceB
가 필요하고, ServiceB
는 ServiceA
가 필요하여 서로를 무한히 기다리는 교착 상태에 빠집니다.
ServiceA.java
@Service
public class ServiceA {
private final ServiceB serviceB;
// ServiceA를 만들려면 ServiceB가 필요하다.
@Autowired
public ServiceA(ServiceB serviceB) {
this.serviceB = serviceB;
}
}
ServiceB.java
@Service
public class ServiceB {
private final ServiceA serviceA;
// ServiceB를 만들려면 ServiceA가 필요하다.
@Autowired
public ServiceB(ServiceA serviceA) {
this.serviceA = serviceA;
}
}
### Spring 컨테이너의 동작 흐름 (실패 과정)
Spring이
ServiceA
Bean을 생성하려고 시도합니다.ServiceA
의 생성자를 보니ServiceB
가 필요합니다.Spring이
ServiceB
Bean을 생성하려고 시도합니다.ServiceB
의 생성자를 보니ServiceA
가 필요합니다.하지만
ServiceA
는ServiceB
를 기다리고 있으므로 아직 생성이 완료되지 않았습니다."A는 B를, B는 A를..." 무한 대기 상태에 빠지며, Spring은
BeanCurrentlyInCreationException
을 발생시키고 애플리케이션을 시작하지 못합니다.
## 예시 2: @Configuration
이 자신의 Bean을 주입받는 경우 (질문 주신 내용)
@Configuration
이 자신의 Bean을 주입받는 경우 (질문 주신 내용)이 경우도 "닭이 먼저냐, 달걀이 먼저냐"와 같은 문제입니다.
AppConfig.java
@Configuration
public class AppConfig {
private final MyService myService; // ◀ 2. MyService를 주입받으려 함
// AppConfig Bean을 만들려면 myService가 필요
@Autowired
public AppConfig(MyService myService) {
this.myService = myService;
}
@Bean // ◀ 1. myService라는 Bean을 여기서 만듦
public MyService myService() {
return new MyService();
}
}
### Spring 컨테이너의 동작 흐름 (실패 과정)
Spring은
@Bean
메서드를 실행하기 위해 먼저@Configuration
클래스인AppConfig
의 Bean을 생성해야 합니다.AppConfig
의 생성자를 보니MyService
Bean이 필요합니다.Spring은
MyService
Bean을 찾으려고 합니다.MyService
Bean은AppConfig
안에 있는myService()
메서드를 실행해야만 만들 수 있습니다.하지만
myService()
메서드를 실행하려면AppConfig
Bean이 먼저 생성되어야 합니다."AppConfig를 만들려면 MyService가, MyService를 만들려면 AppConfig가..." 역시 순환 참조에 빠져 Bean을 생성할 수 없습니다.
Last updated