Spring Boot YAML vs Properties: 설정 파일 비교 및 면접 질문 2026

Spring Boot 4.1의 application.yml과 application.properties를 비교합니다. 구문, 한 파일 안의 여러 프로파일, 우선순위 규칙, Jasypt 암호화, 면접에서 나오는 설정 질문을 다룹니다.

Spring Boot YAML vs Properties: 설정 파일 비교 및 면접 질문 2026

Spring Boot는 application.yml(YAML)과 application.properties(Properties) 두 가지 설정 형식을 기본으로 지원합니다. 현재 릴리스 라인인 Spring Boot 4.1에서는 두 형식 모두 같은 Environment로 로드되고 바인딩 방식도 동일합니다. 차이는 구문, 몇 가지 로딩 규칙, 그리고 두 파일이 같은 위치에 있을 때의 동작에 있습니다.

깊게 중첩된 설정이나 여러 프로파일을 다루는 프로젝트에는 YAML이, 단순한 플랫 설정이나 YAML에 익숙하지 않은 팀에는 Properties가 적합합니다. 다만 두 형식이 완전히 같지는 않습니다. @PropertySource로 로드할 수 있는 것은 Properties뿐이며, 같은 위치에 두 파일이 모두 있으면 .properties의 값이 우선합니다.

Spring Boot 4.1의 YAML과 Properties 비교표

기능YAMLProperties
중첩 설정네이티브 계층 구조점 표기법
한 파일에 여러 프로파일--- 구분자#--- 또는 !--- 구분자
리스트 구문YAML 네이티브 배열인덱스 표기법 [0], [1]
주석모든 행에서 #모든 행에서 # 또는 !
@PropertySource로 로드불가가능
같은 위치에 두 파일이 있을 때덮어써짐우선함
학습 곡선들여쓰기에 민감최소

마지막 두 행은 면접에서 지원자들이 자주 놓치는 부분입니다. Spring Boot 공식 레퍼런스의 외부 설정 문서는 YAML 파일을 @PropertySource나 @TestPropertySource로 로드할 수 없으며, application.properties와 application.yml이 같은 위치에 있으면 .properties의 값이 우선한다고 명시합니다. 공식 권장 사항은 애플리케이션 전체에서 한 가지 형식만 사용하는 것입니다.

기본 구문 비교

Properties 파일과 YAML 파일의 가장 기본적인 차이점은 구문에 있습니다. Properties 파일은 플랫한 키-값 형식을 사용하고, YAML은 계층 구조를 표현할 수 있습니다.

Properties 파일 구문

properties
# application.properties
server.port=8080
server.servlet.context-path=/api

spring.datasource.url=jdbc:postgresql://localhost:5432/mydb
spring.datasource.username=admin
spring.datasource.password=secret
spring.datasource.driver-class-name=org.postgresql.Driver

spring.jpa.hibernate.ddl-auto=update
spring.jpa.show-sql=true
spring.jpa.properties.hibernate.format_sql=true

YAML 파일 구문

yaml
# application.yml
server:
  port: 8080
  servlet:
    context-path: /api

spring:
  datasource:
    url: jdbc:postgresql://localhost:5432/mydb
    username: admin
    password: secret
    driver-class-name: org.postgresql.Driver
  jpa:
    hibernate:
      ddl-auto: update
    show-sql: true
    properties:
      hibernate:
        format_sql: true

YAML 형식에서는 들여쓰기를 통한 계층 구조가 시각적으로 명확하며, 관련 설정 항목들이 그룹화됩니다. 반면 Properties 파일은 단순하고 각 행이 독립적이어서 특정 설정을 검색하기 쉽다는 장점이 있습니다.

프로파일 관리의 차이

Spring Boot의 프로파일 기능은 YAML과 Properties 모두에서 프로파일별 파일과 단일 파일 내 다중 문서를 지원합니다.

Properties에서의 프로파일 관리

properties
# application.properties (공통 설정)
spring.application.name=my-application
logging.level.root=INFO

# application-dev.properties
server.port=8080
spring.datasource.url=jdbc:postgresql://localhost:5432/devdb
logging.level.com.example=DEBUG

# application-prod.properties
server.port=80
spring.datasource.url=jdbc:postgresql://prod-db:5432/proddb
logging.level.com.example=WARN

YAML에서의 프로파일 관리

yaml
# application.yml
spring:
  profiles:
    active: dev

---
spring:
  config:
    activate:
      on-profile: dev
server:
  port: 8080
logging:
  level:
    root: DEBUG

---
spring:
  config:
    activate:
      on-profile: prod
server:
  port: 80
logging:
  level:
    root: WARN

YAML의 --- 구분자를 사용하면 단일 파일 내에서 여러 프로파일 설정을 정의할 수 있습니다. 이는 파일 수를 줄이고 설정의 전체적인 구조를 파악하기 쉽게 만드는 장점이 있습니다.

Properties 파일도 같은 다중 문서 구성을 지원합니다. #---(또는 !---)만 있는 행이 파일을 여러 문서로 나눕니다.

properties
# application.properties
spring.profiles.active=dev
#---
spring.config.activate.on-profile=dev
server.port=8080
logging.level.root=DEBUG
#---
spring.config.activate.on-profile=prod
server.port=80
logging.level.root=WARN

구분자 행은 앞에 공백이 없어야 하고 하이픈은 정확히 세 개여야 합니다. Spring Boot 2.4부터는 두 형식 모두에서 기존의 spring.profiles 대신 spring.config.activate.on-profile 프로퍼티를 사용합니다.

면접 함정

"Properties 파일은 프로파일마다 파일을 따로 만들어야 한다"는 흔한 오답입니다. 다중 문서 .properties 파일은 Spring Boot 2.4부터 사용할 수 있습니다. YAML의 실제 제약은 그 반대 방향으로, @PropertySource로 로드할 수 없다는 점입니다.

프로파일 활성화, 프로파일 그룹, @Profile 빈은 프로파일과 환경 면접 모듈에서 연습할 수 있습니다.

복잡한 데이터 구조 표현

리스트나 맵과 같은 복잡한 데이터 구조를 다룰 때 YAML의 표현력이 두드러집니다.

리스트 구조 비교

properties
# application.properties - 리스트 표현
app.allowed-origins[0]=http://localhost:3000
app.allowed-origins[1]=http://localhost:8080
app.allowed-origins[2]=https://example.com

app.security.roles[0].name=ADMIN
app.security.roles[0].permissions[0]=READ
app.security.roles[0].permissions[1]=WRITE
app.security.roles[0].permissions[2]=DELETE
app.security.roles[1].name=USER
app.security.roles[1].permissions[0]=READ
yaml
# application.yml - 리스트 표현
app:
  allowed-origins:
    - http://localhost:3000
    - http://localhost:8080
    - https://example.com

  security:
    roles:
      - name: ADMIN
        permissions:
          - READ
          - WRITE
          - DELETE
      - name: USER
        permissions:
          - READ

복잡한 중첩 구조에서 YAML의 가독성은 확연히 우수합니다.

설정 프로퍼티 클래스와의 통합

java
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
import java.util.List;

@Component
@ConfigurationProperties(prefix = "app")
public class AppProperties {

    private List<String> allowedOrigins;
    private Security security;

    public static class Security {
        private List<Role> roles;

        public static class Role {
            private String name;
            private List<String> permissions;

            // Getters and Setters
            public String getName() { return name; }
            public void setName(String name) { this.name = name; }
            public List<String> getPermissions() { return permissions; }
            public void setPermissions(List<String> permissions) { 
                this.permissions = permissions; 
            }
        }

        // Getters and Setters
        public List<Role> getRoles() { return roles; }
        public void setRoles(List<Role> roles) { this.roles = roles; }
    }

    // Getters and Setters
    public List<String> getAllowedOrigins() { return allowedOrigins; }
    public void setAllowedOrigins(List<String> allowedOrigins) { 
        this.allowedOrigins = allowedOrigins; 
    }
    public Security getSecurity() { return security; }
    public void setSecurity(Security security) { this.security = security; }
}

환경 변수와 플레이스홀더

두 형식 모두 환경 변수나 플레이스홀더 사용을 지원합니다.

properties
# application.properties
spring.datasource.url=${DATABASE_URL:jdbc:postgresql://localhost:5432/defaultdb}
spring.datasource.username=${DB_USER:root}
spring.datasource.password=${DB_PASSWORD}

app.api-key=${API_KEY:}
app.feature.enabled=${FEATURE_FLAG:false}
yaml
# application.yml
spring:
  datasource:
    url: ${DATABASE_URL:jdbc:postgresql://localhost:5432/defaultdb}
    username: ${DB_USER:root}
    password: ${DB_PASSWORD}

app:
  api-key: ${API_KEY:}
  feature:
    enabled: ${FEATURE_FLAG:false}

spring.config.import로 외부 설정 불러오기

spring.config.import 프로퍼티를 사용하면 기본 위치인 src/main/resources 외의 곳에서 설정을 불러올 수 있습니다. optional: 접두사를 붙이면 파일이 없어도 시작이 실패하지 않습니다. 로컬 개발은 기본값으로 실행하고 운영 환경은 설정 서버에서 설정을 가져오는 구성이 이 방식으로 가능합니다. 설정 파일 관련 연습 문제는 application.properties와 YAML 면접 모듈에 있습니다.

yaml
# application.yml - 임포트 기능
spring:
  config:
    import:
      - optional:file:./config/external.yml
      - optional:configserver:http://config-server:8888
      - classpath:additional-config.yml

---
spring:
  config:
    activate:
      on-cloud-platform: kubernetes
    import:
      - optional:configtree:/etc/config/
java
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.context.properties.bind.ConstructorBinding;
import java.util.List;

@ConfigurationProperties(prefix = "app.mail")
public record MailProperties(
    String host,
    int port,
    String username,
    String password,
    List<String> recipients
) {
    public MailProperties {
        if (port <= 0 || port > 65535) {
            throw new IllegalArgumentException("Invalid port number");
        }
    }
}

성능과 시작 시간

Properties 파일과 YAML 파일의 파싱 성능에는 실질적인 차이가 거의 없습니다. Spring Boot는 시작 시 설정 파일을 한 번만 읽고, 이후에는 캐시된 값을 사용합니다.

java
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.context.properties.ConfigurationPropertiesScan;

@SpringBootApplication
@ConfigurationPropertiesScan
public class Application {

    public static void main(String[] args) {
        long startTime = System.currentTimeMillis();
        SpringApplication.run(Application.class, args);
        long endTime = System.currentTimeMillis();
        System.out.println("Startup time: " + (endTime - startTime) + "ms");
    }
}

면접에서 자주 나오는 질문

Q1: YAML과 Properties의 주요 차이점은 무엇입니까?

YAML은 들여쓰기로 계층 구조를 표현할 수 있고, 복잡한 데이터 구조(리스트, 맵)의 기술이 용이합니다. 반면 Properties는 플랫한 키-값 형식으로 단순한 설정에 적합합니다. 한 파일에 여러 프로파일을 정의하는 것은 YAML(---)과 Properties(#---) 모두 가능합니다. 실제 차이는 @PropertySource로 로드할 수 있는 것이 Properties뿐이라는 점과, 같은 위치에 두 파일이 있으면 .properties가 우선한다는 점입니다.

Q2: 설정 파일의 우선순위를 설명해 주십시오.

Spring Boot는 여러 소스에서 정해진 순서로 설정을 로드하며, 우선순위가 높은 소스가 낮은 소스를 덮어씁니다(공식 목록을 단순화한 것으로, 공식 목록에는 JNDI, 서블릿 파라미터, 테스트 어노테이션도 포함됩니다).

  1. 커맨드라인 인자(--server.port=9000)
  2. SPRING_APPLICATION_JSON(환경 변수나 시스템 프로퍼티에 넣은 인라인 JSON)
  3. Java 시스템 프로퍼티(-Dserver.port=9000)
  4. OS 환경 변수(SERVER_PORT=9000)
  5. 설정 데이터 파일(application.yml, application.properties와 각각의 프로파일별 파일)
  6. @PropertySource 어노테이션
  7. SpringApplication.setDefaultProperties로 지정한 기본 프로퍼티

5번 안에는 두 번째 순서가 있습니다. 프로파일별 파일은 일반 파일을 덮어쓰고, 패키징된 jar 외부의 파일은 jar 내부의 파일을 덮어씁니다. 같은 위치에서는 .properties가 .yml을 덮어씁니다. application.yml에 설정한 값이 아무 경고 없이 무시되는 이유(옆에 남아 있는 application.properties)를 설명할 수 있는 지원자는 실제 디버깅 경험을 보여 줍니다.

Q3: @Value와 @ConfigurationProperties의 차이점은?

java
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

@Component
public class ValueExample {
    
    @Value("${app.name}")
    private String appName;
    
    @Value("${app.timeout:5000}")
    private int timeout;
    
    @Value("#{${app.map}}")
    private Map<String, String> configMap;
}

@Value는 개별 프로퍼티 주입에 적합하고, @ConfigurationProperties는 관련 프로퍼티의 그룹화, 타입 안전성, 검증 기능을 제공합니다.

Q4: 민감한 설정 값은 어떻게 다룹니까?

시크릿은 절대 버전 관리 시스템에 커밋하지 않습니다. 기본은 환경 변수 참조입니다.

yaml
# application.yml - reference environment variable
spring:
  datasource:
    password: ${DB_PASSWORD}

운영 시스템에서는 Spring Cloud Config Server나 HashiCorp Vault로 시크릿을 중앙에서 관리합니다. 민감한 엔드포인트 보호는 Actuator 모니터링 가이드에서 다룹니다.

Q5: Jasypt란 무엇이며 Spring Boot 프로퍼티를 어떻게 암호화합니까?

Jasypt Spring Boot는 Environment가 구성될 때 ENC(...)로 감싼 값을 복호화합니다. 따라서 암호화된 시크릿을 application.yml이나 application.properties에 두고도 일반 값처럼 바인딩할 수 있습니다.

properties
# application.properties
spring.datasource.password=ENC(nrmZtkF7T0kjG/VodDvBw93Ct8EgjCA+)
bash
# The master password is supplied at runtime, never committed
java -Djasypt.encryptor.password=$JASYPT_MASTER_KEY -jar app.jar

필수 프로퍼티는 jasypt.encryptor.password 하나뿐이며, 기본 알고리즘은 PBEWITHHMACSHA512ANDAES_256입니다. 형식에 따른 차이는 없어서 같은 ENC(...) 값이 YAML과 Properties 모두에서 동작합니다.

시니어 지원자를 구분하는 답변은 다음과 같습니다. Jasypt는 시크릿을 없애는 것이 아니라 옮길 뿐입니다. 마스터 패스워드를 가진 사람은 저장소의 모든 값을 복호화할 수 있고, 마스터 패스워드를 교체하려면 모든 값을 다시 암호화해야 합니다. Vault나 클라우드 시크릿 매니저는 접근 제어, 감사, 교체 기능을 제공하지만 Jasypt에는 이 기능이 없습니다.

업그레이드 전 호환성 확인

4.0.x 스타터(4.0.4, 2026년 1월)는 Java 17과 Spring Boot 3.5 이상을 요구하며, README에는 Spring Boot 4가 명시되어 있지 않습니다. 기반이 되는 Jasypt 라이브러리는 2019년 5월의 1.9.3 이후 릴리스가 없습니다. Jasypt 기반 프로젝트를 Spring Boot 4로 옮기기 전에 별도 브랜치에서 스타터를 검증해야 합니다.

Spring Boot 면접 준비가 되셨나요?

인터랙티브 시뮬레이터, flashcards, 기술 테스트로 연습하세요.

모범 사례

1. 일관성 유지

프로젝트 내에서 하나의 형식으로 통일하는 것을 권장합니다. 혼재하면 설정 관리가 복잡해집니다. 같은 위치에 application.properties와 application.yml이 있으면 .properties의 값이 우선하므로, YAML 쪽에 쓴 값이 아무 경고 없이 덮어써집니다.

2. 환경별 설정 분리

yaml
# application.yml - 공통 설정만
spring:
  application:
    name: my-service
  profiles:
    active: ${SPRING_PROFILES_ACTIVE:dev}

3. 민감 정보 관리

yaml
# 민감 정보는 환경 변수에서 가져오기
spring:
  datasource:
    password: ${DB_PASSWORD}

app:
  jwt:
    secret: ${JWT_SECRET}

4. 시작 시점 검증

java
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.Positive;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.validation.annotation.Validated;

@Validated
@ConfigurationProperties(prefix = "app")
public class ValidatedAppProperties {

    @NotBlank(message = "Application name is required")
    private String name;

    @Positive(message = "Timeout must be positive")
    private int timeout;

    // Getters and Setters
    public String getName() { return name; }
    public void setName(String name) { this.name = name; }
    public int getTimeout() { return timeout; }
    public void setTimeout(int timeout) { this.timeout = timeout; }
}

참고 자료

연습을 시작하세요!

면접 시뮬레이터와 기술 테스트로 지식을 테스트하세요.

Spring Boot 설정 파일 선택의 핵심 정리

  • YAML은 공통 접두사를 가진 설정의 반복을 줄이고 리스트를 더 간결하게 표현합니다
  • Properties는 플랫한 설정이나 YAML 구문에 익숙하지 않은 팀에 적합합니다
  • Spring Boot 4.1은 @ConfigurationProperties 바인딩과 검증에서 두 형식을 동일하게 처리합니다
  • 두 형식 모두 한 파일에 여러 프로파일을 정의할 수 있습니다. YAML은 ---, Properties는 #---를 사용합니다
  • 같은 위치에 두 파일이 모두 있으면 .properties가 우선하며, @PropertySource로 로드할 수 있는 것은 Properties뿐입니다
  • 설정 우선순위는 정해져 있으며, 커맨드라인 인자가 환경 변수를, 환경 변수가 파일 기반 설정을 덮어씁니다
  • 민감한 값은 환경 변수나 시크릿 관리 시스템에 둡니다. Jasypt의 ENC(...)는 시크릿을 마스터 패스워드로 옮길 뿐입니다
  • 운영 환경에서는 spring.config.import로 외부 소스의 설정을 불러옵니다

면접에서는 두 형식의 특징을 이해하고 실제 유스케이스에 맞는 선택을 할 수 있음을 보여 주는 것이 요구됩니다.

오늘의 챌린지

Spring Boot 코드의 버그를 찾을 수 있나요

실제 코드 한 조각, 숨은 버그 하나, 하루 한 번. 계정 없이 바로 도전할 수 있습니다.

Anthony Fillion-Maillet

작성자

Anthony Fillion-Maillet

SharpSkill 창업자

10년 이상 풀스택 개발을 해왔습니다. SharpSkill을 운영하며 이곳에 게시되는 모든 내용에 책임을 집니다.

2026년 10월 27일 업데이트

공유

관련 기사