..
[오류 해결] Spring 순환 참조(Circular Reference) 발생 원인과 해결
1. 문제 발생
애플리케이션 배포 후 구동 과정에서 다음과 같은 APPLICATION FAILED TO START 오류 메시지와 함께 서버가 멈추는 현상이 발생했습니다.
The dependencies of some of the beans in the application context form a cycle:
┌─────┐
| loginServiceImpl -> tcpipMessageServiceImpl
↑ ↓
| tcpipMessageServiceImpl -> gfFdsServiceImpl
↑ ↓
| gfFdsServiceImpl -> loginServiceImpl
└─────┘
2. 순환 참조(Circular Reference)란?
서로 다른 빈(Bean)들이 서로를 의존하고 있어 꼬리에 꼬리를 무는 사이클이 형성된 상태를 의미합니다. 스프링 컨테이너는 빈을 생성할 때 의존 관계를 파악하여 순차적으로 주입하는데, 위와 같이 서로가 서로를 필요로 하면 “누굴 먼저 만들어야 할지” 결정하지 못하게 됩니다.
“순환 참조 오류는 프로그램의 설계가 잘못되었으니 구조를 개선하라는 스프링의 강력한 경고입니다.”
3. 해결 방법
방법 1: 서비스 레이어 재설계 (권장)
가장 근본적인 해결책입니다. 서로 얽혀있는 매듭을 풀어서 단방향 흐름으로 바꿉니다. 공통으로 필요한 로직을 별도의 헬퍼(Helper) 클래스나 유틸리티 서비스로 추출하여 의존성 화살표가 한쪽으로만 향하게 조정합니다.
- 개선 전:
A -> B -> C -> A(순환) - 개선 후:
A -> B -> C(단방향)
방법 2: 임시 허용 옵션 사용 (미봉책)
비즈니스 일정상 즉시 리팩토링이 어렵다면 스프링 부트 설정을 통해 임시로 구동을 허용할 수 있습니다. (하지만 잠재적인 문제를 덮어두는 것이므로 권장하지 않습니다.)
# application.yml
spring:
main:
allow-circular-references: true
순환 참조는 객체 간의 역할 분담이 명확하지 않을 때 발생합니다. 이 오류를 만났다면 코드의 책임(Responsibility)을 다시 한번 검토해 볼 기회로 삼는 것이 좋습니다.