[Spring Boot] YAML Configuration: multi-document, profiles, anchors
정의
Spring Boot 는 application.properties 와 application.yml 모두 지원. YAML 권장: 계층 구조 가독성, multi-document, anchors / aliases, list / map native 지원.
설정 파일 search order (classpath):
application.yml/application.yamlapplication.properties
두 파일 동시 있으면 properties 가 우선 (Spring Boot 의 default ordering).
기본 문법
spring:
application:
name: my-app
datasource:
url: jdbc:postgresql://localhost/db
username: app
pool:
max-size: 20
min-idle: 5
jpa:
show-sql: true
properties:
hibernate:
format_sql: true
= properties:
spring.application.name=my-app
spring.datasource.url=jdbc:postgresql://localhost/db
spring.datasource.username=app
spring.datasource.pool.max-size=20
spring.datasource.pool.min-idle=5
spring.jpa.show-sql=true
spring.jpa.properties.hibernate.format_sql=true
들여쓰기 = 2 space 권장. tab 금지.
List
spring:
profiles:
active:
- web
- dev
# 또는 inline
spring.profiles.active: [web, dev]
properties:
spring.profiles.active[0]=web
spring.profiles.active[1]=dev
# 또는
spring.profiles.active=web,dev
YAML 의 list 가 훨씬 가독성 좋음.
Map
app:
features:
new-checkout: true
legacy-cart: false
rate-limit: 100
@ConfigurationProperties(prefix = "app")
public class AppProps {
private Map<String, Object> features; // 자동 매핑
}
Multi-document (한 파일 다 profile)
# 기본 (모든 profile 에 적용)
spring:
application:
name: my-app
logging:
level:
org.springframework: INFO
---
# dev 만
spring:
config:
activate:
on-profile: dev
server:
port: 8080
datasource:
url: jdbc:h2:mem:devdb
---
# prod 만
spring:
config:
activate:
on-profile: prod
server:
port: 80
datasource:
url: jdbc:postgresql://prod-db/myapp
--- 가 document separator. Spring Boot 가 활성 profile 에 해당하는 document 만 적용.
spring.config.activate.on-profile 가 modern 문법 (Spring Boot 2.4+). 이전엔 spring.profiles 였음.
@ 와 ${} 의 차이
app:
version: @project.version@ # Maven / Gradle resource filtering (빌드 타임)
user: ${USER:default} # 환경 변수 또는 default (런타임)
secret: ${random.value} # Spring Boot built-in
nested: ${app.user}-suffix # 다른 property 참조
@var@: build tool 이 치환. spring-boot-maven-plugin 의 resource filtering.
${var}: Spring Boot 의 PropertyPlaceholder. environment variable / 다른 property / SpEL.
Profile-specific 파일
src/main/resources/
├── application.yml ← 공통
├── application-dev.yml ← dev 만 (active 가 dev 일 때)
├── application-prod.yml ← prod
├── application-test.yml ← test
└── application-local.yml ← 개인 로컬 (gitignore)
활성화:
spring.profiles.active: dev
또는 환경 변수:
SPRING_PROFILES_ACTIVE=dev java -jar app.jar
YAML Anchors & Aliases
DRY 를 위한 YAML 자체 기능:
defaults: &defaults
timeout: 30s
retries: 3
pool-size: 10
services:
user-api:
<<: *defaults
url: http://user-api
order-api:
<<: *defaults
url: http://order-api
timeout: 60s # 오버라이드
&defaults : anchor 정의. *defaults : 참조. << : merge.
Spring Boot 의 binding 은 final flat property 만 보므로 anchor 가 작동. 단, Snakeyaml 의 일부 버전 / 옵션은 anchor 비활성화 가능. spring.yaml.bind.enable-merge=true 옵션.
Multiline 문자열
# literal (개행 유지)
description: |
Line 1
Line 2
Line 3
# folded (개행 → 공백)
description: >
This is a long
description that
becomes single line.
# preserve indent
description: |+
Line 1
Line 3
숫자 / boolean / null
# boolean
debug: true # OK
debug: yes # ❌ deprecated YAML (1.2 부터 boolean 아님)
debug: "yes" # string
# null
unused: ~ # null
unused: null # null
unused: # null (빈 값)
unused: "" # 빈 문자열
# 숫자
port: 8080 # int
ratio: 0.5 # float
big: 1_000_000 # 가독성 (Spring Boot 3+ 지원)
# string with special chars
url: "jdbc:postgresql://host:5432/db?ssl=true"
yes / no 가 boolean 으로 처리 안 됨. 명시적 true / false 권장.
spring.config.import
다른 설정 파일 / 외부 소스 import:
spring:
config:
import:
- "classpath:database.yml"
- "optional:file:./config/local.yml"
- "configtree:/run/secrets/" # K8s secrets
- "vault://" # Spring Cloud Vault
- "consul://" # Spring Cloud Consul
optional:: 없어도 에러 안 남file:: 파일시스템classpath:: 리소스configtree:: 디렉토리 = 각 파일이 propertyvault://,consul://: Spring Cloud config server
OS Environment Override
spring:
datasource:
url: ${SPRING_DATASOURCE_URL:jdbc:h2:mem:test}
username: ${DB_USER:admin}
password: ${DB_PASSWORD:} # 빈 default
Docker / K8s 환경에서 일반적 패턴. 환경 변수 없으면 default 또는 H2 임시.
운영 / 개발 분리 패턴
패턴 1: profile
# application.yml
spring:
profiles:
active: ${APP_ENV:dev}
# application-dev.yml
spring:
datasource:
url: jdbc:h2:mem:devdb
# application-prod.yml
spring:
datasource:
url: ${PROD_DB_URL}
패턴 2: 환경 변수만
spring:
datasource:
url: ${DATABASE_URL:jdbc:h2:mem:devdb}
profile 없이 환경 변수로만 분기. 12-factor app 권장 패턴.
패턴 3: 외부 파일 import
spring:
config:
import: "optional:file:./config/env.yml"
배포 시 config/env.yml 만 교체.
검증
# spring-boot-properties-migrator
./gradlew bootRun --args='--spring.profiles.active=prod'
# 시작 로그에 모든 PropertySource 출력
# Actuator endpoint
GET /actuator/configprops
GET /actuator/env
함정과 베스트 프랙티스
- 들여쓰기 2 space, 절대 tab 금지
yes/noboolean 안 됨:true/false명시- profile 활성화는 환경 변수 권장:
SPRING_PROFILES_ACTIVE=dev - secret 은 yml 평문 금지: 환경 변수 / secret manager
@ConfigurationProperties와 함께 쓰면 IDE 자동완성 + 검증spring.config.import가 modern 패턴:@PropertySource보다 우선- multi-document 는 같은 파일에서 환경 분리할 때: 별도 파일 (
application-{profile}.yml) 도 OK - default profile:
spring.profiles.default=dev(active 가 set 안 됐을 때) - profile 그룹:
spring.profiles.group.staging=cloud,monitoring으로 묶기
관련 위키
이 글의 용어 (4개)
- [Spring Boot] 자동 구성과 @SpringBootApplicationspring
- 정의 Spring Boot의 핵심 가치 = 자동 구성(autoconfiguration). classpath의 라이브러리를 보고 합리적 기본 설정으로 Bean 등록. Tomcat이…
- [Spring Boot] Properties 외부화: PropertySource, Profile, @ConfigurationPropertiesspring
- 정의 Spring Boot 는 설정값을 15가지 소스에서 우선순위로 병합. 같은 키가 여러 곳에 있으면 우선순위 높은 게 이김. 코드 변경 없이 환경별 설정 가능. 핵심 소스 (…
- [Spring Cloud] Eureka, Config, Gateway, OpenFeignspring
- 정의 Spring Cloud는 Spring Boot 기반 마이크로서비스 인프라 패턴 (service discovery, config server, gateway, circuit …
- [Spring] @Conditional, Profile, @ConfigurationPropertiesspring
- 정의 Spring Boot는 조건부 Bean 등록 메커니즘을 제공한다. classpath, property, 다른 Bean 유무 등에 따라 자동 구성을 활성화/비활성화. , 어노…
💬 댓글