본문으로 건너뛰기

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.

덮어쓰기 순서(같은 키일 때 뒤에 나온 쪽이 이김):

  1. application.yml (공통)
  2. application-{profile}.yml (활성 프로파일)

application-prod.yml의 값이 application.yml보다 우선합니다.

5.3 외부 설정 우선순위 (요약)

Spring Boot 문서 기준, 동일 키 에 대해 아래 순서로 우선순위가 높아집니다 (높은 것이 최종 적용).

  1. 커맨드 라인 인자--server.port=8081
  2. SPRING_APPLICATION_JSON(환경 변수/시스템 프로퍼티에 JSON)
  3. ServletConfig / ServletContext(웹 환경)
  4. JNDI
  5. Java 시스템 프로퍼티-Dserver.port=8081
  6. OS 환경 변수
  7. RandomValuePropertySource(random.*)
  8. jar 외부의 application-{profile}.yml(패키징된 jar 기준)
  9. jar 내부의 application-{profile}.yml
  10. jar 외부의 application.yml
  11. jar 내부의 application.yml
  12. @PropertySource
  13. 기본값(SpringBootApplication 기본 등)

실무에서는 기본값은 jar 내부 application.yml, 환경별 덮어쓰기는 application-{profile}.yml 또는 환경 변수·커맨드 라인 으로 두는 패턴이 많습니다.

5.4 정리

  • 설정 경로: ./config/ > ./ > classpath:/config/ > classpath:/
  • 파일 종류: application-{profile}.ymlapplication.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. 설정 파일 로딩 순서와 우선순위 를 참고하세요.