Spring Boot의 설정 파일 로딩 메커니즘과 외부 라이브러리 사용 시 발생하는 문제를 다룹니다.
ConfigData API (Spring Boot 2.4+)
Spring Boot 2.4 부터 설정 로딩 방식이 ConfigData API로 변경되었습니다.
주요 변경사항
- Spring Cloud Bootstrap Context 대체 (bootstrap.yml → application.yml)
- 단일 ApplicationContext 사용
spring.config.import도입
설정 파일 로딩 기본 동작
검색 위치
Spring Boot는 다음 위치에서 설정 파일을 검색합니다 (낮은 → 높은 우선순위):
1. classpath:/application.yml
2. classpath:/config/application.yml
3. file:./application.yml
4. file:./config/application.yml
5. file:./config/*/application.yml
로딩 규칙
- 다른 경로: 모두 로드 후 병합
- 같은 classpath 경로: 첫 번째만 사용
- Oracle Java 문서: 여러 모듈이 동일한 클래스 로더에 정의되고, 둘 이상의 모듈이 주어진 이름의 리소스를 포함하는 경우, 모듈이 검색되는 순서는 명시되지 않으며 매우 예측할 수 없을 수 있습니다.
우선순위
나중에 로드된 것이 우선:
# classpath:/application.yml
server.port: 8080
server.timeout: 30
# file:./config/application.yml
server.port: 9090
# 결과
server.port: 9090 # 덮어쓰기
server.timeout: 30 # 유지
외부 라이브러리 JAR의 application.yml 충돌 문제
문제 상황
my-app/src/main/resources/
- config/application.yml // classpath:/config/application.yml
external-sdk.jar/
- config/application.yml // classpath:/config/application.yml (동일!)
실제 동작
- my-app과 external-sdk 중 하나만 로드됨
- 어느 것이 로드될지는 classpath 순서 의존 (비결정적)
- 나머지는 완전히 무시 (병합 X)
// Spring Boot 내부 코드
Resource resource = resourceLoader.getResource("classpath:/config/application.yml");
// → ClassLoader.getResource() 사용
// → 첫 번째 발견된 파일만 반환!
올바른 해결 방법
라이브러리는 고유한 파일명 사용
# 하지 말아야 할 것
external-sdk.jar/application.yml # 위험!
# 올바른 방법
external-sdk.jar/sdk-defaults.yml # 고유 이름
classpath: vs classpath*: 차이
| 접두사 | 내부 메서드 | 동작 | 사용 예 |
|---|---|---|---|
classpath: |
getResource() |
첫 번째만 반환 | Spring Boot 기본값 |
classpath*: |
getResources() |
모두 반환 | 명시적 스캔 필요시 |
정리
핵심 원칙
- 라이브러리에
application.yml사용 금지 - 설정 파일명을 네임스페이스로 관리
spring.config.import로 명시적 제어
이 문제는 Java ClassLoader의 근본적인 동작이며, Spring Boot Issue #24688에서 개선이 논의 중입니다.