2.5 환경 변수와 설정 프로퍼티 (application.yml, @ConfigurationProperties)
application.yml의 값을 타입에 맞게 바인딩하고 검증하려면 @ConfigurationProperties 를 사용합니다. @Value 여러 개보다 구조가 명확하고, IDE 자동완성·검증에 유리합니다.
작성 기준: Spring Boot 3.2.x
1. 기본 사용
# application.yml
app:
mail:
host: smtp.example.com
port: 587
security:
jwt-secret: my-secret
token-validity: 3600
@Configuration
@ConfigurationProperties(prefix = "app")
@Validated
@Getter
@Setter
public class AppProperties {
private final Mail mail = new Mail();
private final Security security = new Security();
@Getter
@Setter
public static class Mail {
private String host = "localhost";
private int port = 25;
}
@Getter
@Setter
public static class Security {
@NotBlank
private String jwtSecret;
@Min(60)
private long tokenValidity = 3600;
}
}
- prefix: yaml의 최상위 키 (
app) - @Validated+ Bean Validation으로 기동 시 검증 가능 (필수 값 누락 시 빌드 실패)
2. 스캔 활성화
@EnableConfigurationProperties(AppProperties.class) 또는 해당 클래스를 @Component 로 두면 빈으로 등록됩니다.
Spring Boot는 @ConfigurationProperties 가 붙은 클래스를 자동 스캔하므로, 보통은 @Configuration 만 있어도 됩니다.
3. 프로파일별 값
# application-dev.yml
app:
mail:
host: mailhog
port: 1025
---
# application-prod.yml
app:
mail:
host: ${MAIL_HOST}
port: ${MAIL_PORT:587}
${ENV_VAR}: 환경 변수${ENV_VAR:default}: 기본값
4. 생성자 바인딩 (불변)
Spring Boot 2.2+에서는 생성자 로 바인딩할 수 있어, final 필드로 불변 설정을 만들 수 있습니다.
@ConfigurationProperties(prefix = "app.mail")
@ConstructorBinding // Boot 3.x에서는 단일 생성자 시 생략 가능
@Getter
public class MailProperties {
private final String host;
private final int port;
public MailProperties(String host, int port) {
this.host = host;
this.port = port;
}
}
5. Spring Boot 설정 파일 로딩 순서와 우선순위
애플리케이션 설정(application.properties / application.yml)은 여러 위치 에서 로드되고, 나중에 로드된 값 이 먼저 로드된 값 을 덮어씁니다. 같은 키가 여러 곳에 있으면 우선순위가 높은 쪽 이 최종 적용됩니다.
5.1 설정 파일 검색 경로 (위에서 아래로 우선순위 낮음)
Spring Boot(2.4+)는 아래 순서로 application.properties/ application.yml(및 application-{profile}.yml)을 찾습니다. 숫자가 작을수록 우선순위가 높으며, 외부 시스템의 설정이 패키징된 내부 설정을 덮어씁니다.
| 순위 | 경로 (Locations) | 비고 |
|---|---|---|
| 1 | 커맨드 라인 지정 경로 | java -jar app.jar --spring.config.location=... |
| 2 | 현재 디렉터리의 /config 하위 폴더들 | ./config/*/application.yml (다중 설정 분리 시 유용) |
| 3 | 현재 디렉터리의 /config | ./config/application.yml |
| 4 | 현재 디렉터리 | ./application.yml |
| 5 | 클래스패스의 /config 패키지 | classpath:/config/application.yml |
| 6 | 클래스패스 루트 | classpath:/application.yml (보통 src/main/resources) |
- 외부 설정 파일의 강력함: 배포된
jar파일과 같은 위치에application.yml을 두거나config/폴더를 만들어 설정 파일을 위치시키면, 소스 코드(jar 내부)에 하드코딩된 설정을 재컴파일 없이 통째로 덮어쓸 수 있습니다. spring.config.additional-location: 기존 클래스패스 검색 경로를 유지하면서 외부 파일만 추가 로 덮어쓰려면 이 옵션을 커맨드 라인 인자로 줍니다. (예:--spring.config.additional-location=file:./custom.yml)
5.2 프로파일별 파일과 공통 파일
- application.yml: 공통. 프로파일 없이 로드.
application-{profile}.yml: 해당 프로파일이 활성화될 때 추가 로드. 예:application-dev.yml,application-prod.yml.
덮어쓰기 순서(같은 키일 때 뒤에 나온 쪽이 이김):
- application.yml (공통)
application-{profile}.yml(활성 프로파일)
즉 application-prod.yml의 값이 application.yml보다 우선합니다.
5.3 외부 설정 우선순위 (요약)
Spring Boot 문서 기준, 동일 키 에 대해 아래 순서로 우선순위가 높아집니다 (높은 것이 최종 적용).
- 커맨드 라인 인자—
--server.port=8081 - SPRING_APPLICATION_JSON(환경 변수/시스템 프로퍼티에 JSON)
- ServletConfig / ServletContext(웹 환경)
- JNDI
- Java 시스템 프로퍼티—
-Dserver.port=8081 - OS 환경 변수
- RandomValuePropertySource(
random.*) - jar 외부의
application-{profile}.yml(패키징된 jar 기준) - jar 내부의
application-{profile}.yml - jar 외부의 application.yml
- jar 내부의 application.yml
- @PropertySource
- 기본값(SpringBootApplication 기본 등)
실무에서는 기본값은 jar 내부 application.yml, 환경별 덮어쓰기는 application-{profile}.yml 또는 환경 변수·커맨드 라인 으로 두는 패턴이 많습니다.
5.4 정리
- 설정 경로:
./config/>./>classpath:/config/>classpath:/ - 파일 종류:
application-{profile}.yml이application.yml보다 같은 키에 대해 우선. - 외부 덮어쓰기: 커맨드 라인·환경 변수가 파일보다 우선하므로, 비밀번호·포트 등은 배포 시 외부에서 주입할 수 있습니다.
6. List / Map
app:
allowed-hosts:
- api.example.com
- admin.example.com
features:
new-ui: true
beta: false
private List<String> allowedHosts = new ArrayList<>();
private Map<String, Boolean> features = new HashMap<>();
민감 정보는 환경 변수 나 Vault 로 주입하고, @ConfigurationProperties에서는 ${VAR}로 참조하는 방식을 권장합니다. 어떤 값이 최종 적용되는지 확인할 때는 위 5. 설정 파일 로딩 순서와 우선순위 를 참고하세요.