컴포넌트 스캔 범위 확장으로 터진 빈 이름 충돌 해소
목차
서버가 안 뜬다
월요일 아침 출근하자마자 빌드는 통과했는데 기동 단계에서 컨테이너가 죽음. 로그 맨 아래 한 줄이 모든 걸 설명해줬음.
ConflictingBeanDefinitionException:
Annotation-specified bean name 'xxxController' for
bean class [com.example.biz.XxxController] conflicts
with existing, non-compatible bean definition of
same name and class [com.example.legacy.XxxController]
같은 이름의 컴포넌트가 두 패키지에 살고 있었던 거. 한 쪽은 신규 비즈 도메인, 다른 한 쪽은 옛 레거시 잔재. 둘 다 디폴트 이름으로 빈 등록을 시도하니 컨테이너가 둘 중 누구를 줄 세울지 못 정하고 손 들어버림.
왜 이제서야 터졌나
| 시점 | 상태 | 영향 |
|---|---|---|
| 작년 | 레거시 패키지만 존재 | 정상 |
| 두 달 전 | 신규 패키지 추가, 클래스명 동일 | 잠복 |
| 지난주 | 컴포넌트 스캔 범위가 양쪽으로 확장 | 충돌 노출 |
핵심은 "두 클래스가 동시에 스캔되기 시작한 순간 터졌다" 는 점. 클래스명 자체는 두 달 전부터 겹쳐 있었는데, 그동안은 한 쪽이 스캔 범위 밖이라 조용했음. 컴포넌트 스캔의 베이스 패키지를 상위로 끌어올린 PR이 트리거였음.
고친 방법
세 가지 옵션을 두고 저울질함.
- A. 신규 클래스 이름 변경 → 호출부 전부 손대야 함. 부담 큼.
- B. 레거시 삭제 → 진짜 안 쓰는지 확인이 필요. 시간 부족.
- C. 빈 이름만 명시적으로 분리 → 가장 작은 변경, 복구 우선.
기동 실패 상황이라 C 선택. 신규 쪽에 명시적 빈 이름을 박아넣어 충돌만 즉시 해소하고, 레거시 정리는 별도 티켓으로 분리.
회고
- 기본 빈 이름은 클래스 단순명 기반이라는 걸 다들 머리로는 알지만, 패키지를 다르게 두면 괜찮을 거라 무의식적으로 믿음. 아님.
- 컴포넌트 스캔 범위를 넓히는 변경은 "새 빈을 추가하는 변경" 과 동급으로 위험함. PR 리뷰 체크리스트에 추가했음.
- 빌드 그린 != 부팅 그린. 정적 컴파일이 잡아주지 못하는 런타임 충돌은 반드시 컨테이너 기동 단계의 스모크 테스트 로 거른다.
- 핫픽스는 작게, 정리는 따로. 기동 실패 상황에서 리팩터까지 욕심내면 롤백도 못 하고 상황만 꼬임.
레거시 클래스 정리 티켓은 다음 스프린트로 넘겼음. 같은 이름의 빈이 살아있는 한 시한폭탄은 그대로니까.
다음
댓글 0
첫 댓글 달아줘.