[Spring Boot] application.yml 설정파일 마스타~~

2025. 9. 14. 20:57·공부일기../Spring


인트로

Spring Boot 프로젝트를 시작하면 가장 먼저 마주치는 파일 중 하나가 바로 `application.yml`이다.

이 설정 파일이 어떻게 애플리케이션 전체를 제어하는지에 대해서 포스팅해보려고한다. 보통 설정파일을 제대로 보려고 하지않았기 때문에 소소한 문제가 생겨도 해결하는데 어려움이 있었다.

 

오늘은 application.yml의 역할부터 활용법까지 모든 것을 포스팅해보도록하겠다.

 

 


 

1. application.yml이란?

`application.yml`은 Spring Boot 애플리케이션의 설정 정보를 담는 핵심 파일이다.

YAML(YAML Ain't Markup Language) 형식으로 작성되며, 애플리케이션의 다양한 속성과 구성 값을 계층적 구조로 정의할 수 있다.

더보기

 

 


 

2. 왜 YAML을 사용할까?

application.yml 파일
application.properties 파일


기존의 .properties 파일과 비교했을 때 YAML은 아래와같은 장점이있다.

  • 가독성: 계층적 구조로 설정을 표현해 더 직관적
  • 간결성: 중복되는 키를 줄여 코드량 감소
  • 타입 지원: 문자열, 숫자, 불린, 배열 등 다양한 데이터 타입 지원

 

 

 


 

3. YAML vs Properties 비교

3-1. Properties 파일 방식

spring.application.name=my-app
spring.datasource.url=jdbc:mysql://localhost:3306/mydb
spring.datasource.username=user
spring.datasource.password=password
spring.jpa.hibernate.ddl-auto=update
server.port=8080

3-2. YAML 파일 방식

spring:
  application:
    name: my-app
  datasource:
    url: jdbc:mysql://localhost:3306/mydb
    username: user
    password: password
  jpa:
    hibernate:
      ddl-auto: update

server:
  port: 8080

 

 

 

 


 

4. application.yml의 주요 기능

4-1. 애플리케이션 설정 관리

가장 기본적인 역할은 애플리케이션의 핵심 설정들을 관리하는 것이다:

spring:
  application:
    name: domain-driven  # 애플리케이션 이름
  
server:
  port: 8080  # 서버 포트
  servlet:
    context-path: /api  # 컨텍스트 경로

 

4-2. 데이터베이스 연결 설정

spring:
  datasource:
    url: jdbc:mysql://localhost:3306/mydb
    username: ${DB_USERNAME:defaultuser}
    password: ${DB_PASSWORD:defaultpass}
    driver-class-name: com.mysql.cj.jdbc.Driver
  
  jpa:
    hibernate:
      ddl-auto: update
    show-sql: true
    properties:
      hibernate:
        dialect: org.hibernate.dialect.MySQL8Dialect

4-3. 로깅 설정

logging:
  level:
    root: INFO
    com.example: DEBUG
    org.springframework.security: DEBUG
  pattern:
    console: "%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n"
  file:
    name: logs/application.log

 

 

 


 

 

5. 프로필 기반 설정

환경별로 다른 설정을 사용할 수 있다.

물리적인 파일은 한개지만 논리적으로 프로필을 분리해서 사용 할 수 있고,(이커머스 프로젝트를하면서 이거때문에 설정문제가 제법있었다.. 잘몰라서 이름을 잘못설정함ㅋㅋ)

실제로 파일을 물리적으로 분리해서 사용 할 수도 있다.

5-1. 단일 파일에서 프로필 분리

spring:
  application:
    name: my-app
  profiles:
    active: dev
#---
spring:
  profiles: dev
  datasource:
    url: jdbc:h2:mem:devdb
  logging:
    level:
      root: DEBUG
#---
spring:
  profiles: prod
  datasource:
    url: jdbc:mysql://prod-server:3306/proddb
  logging:
    level:
      root: WARN

 

5-2. 파일 분리 방식

  • application.yml (공통 설정)
  • application-dev.yml (개발 환경)
  • application-prod.yml (운영 환경)
  • application-test.yml (테스트 환경)

파일분리방식 설정 

5-1의 단일프로필설정 처럼 파일분리방식도 application.yml파일에 active : dev를 하면 자동으로 dev파일을 읽는다.

 

터미널에서 변경하거나 ide자체에서 변경하는법도 있는거같지만.. 잘모르겠구

회사에서는 메인 클래스에서 시스템 속성으로 설정을 했던거같음..!!

더보기
@SpringBootApplication
@Slf4j
public class MyApplication {

    public static void main(String[] args) {
        // main 메서드 실행 전에 시스템 속성으로 프로필 설정
        System.setProperty("spring.profiles.active", "dev");
        
        log.info("애플리케이션 시작 - 프로필: dev");
        SpringApplication.run(MyApplication.class, args);
    }
}

 

 


 

6. 자주 사용하는 설정들

6-1. application.yml 예시

spring:
  application:
    name: domain-driven
  
  # 데이터베이스 설정
  datasource:
    url: jdbc:mysql://localhost:3306/ddd_db
    username: ${DB_USERNAME:root}
    password: ${DB_PASSWORD:password}
    driver-class-name: com.mysql.cj.jdbc.Driver
    hikari:
      maximum-pool-size: 20
      minimum-idle: 5
      connection-timeout: 20000
  
  # JPA 설정
  jpa:
    hibernate:
      ddl-auto: validate
    show-sql: false
    properties:
      hibernate:
        dialect: org.hibernate.dialect.MySQL8Dialect
        format_sql: true
  
  # Redis 설정 (캐시)
  redis:
    host: localhost
    port: 6379
    timeout: 2000ms
    lettuce:
      pool:
        max-active: 8
        max-idle: 8
        min-idle: 0

# 서버 설정
server:
  port: 8080
  servlet:
    context-path: /api/v1
  compression:
    enabled: true
  error:
    include-stacktrace: never

# 로깅 설정
logging:
  level:
    root: INFO
    com.example.ddd: DEBUG
    org.springframework.security: WARN
  pattern:
    file: "%d{ISO8601} [%thread] %-5level %logger{36} - %msg%n"
  file:
    name: logs/application.log
    max-size: 10MB
    max-history: 30

# 커스텀 설정
app:
  jwt:
    secret: ${JWT_SECRET:mySecretKey}
    expiration: 86400000  # 24시간
  file:
    upload-dir: /uploads
    max-size: 10MB

 

 

 

 


 

7. 환경 변수와 프로퍼티 바인딩

7-1. 환경 변수 사용

spring:
  datasource:
    username: ${DB_USERNAME:defaultuser}
    password: ${DB_PASSWORD}  # 기본값 없음 (필수)
    url: ${DATABASE_URL:jdbc:h2:mem:testdb}

7-2. 설정 클래스와 바인딩

app:
  jwt:
    secret: mySecret
    expiration: 86400000
  file:
    upload-dir: /uploads
    max-size: 10MB

 

해당하는 Java 설정 클래스:

@ConfigurationProperties(prefix = "app")
@Data
public class AppProperties {
    private Jwt jwt = new Jwt();
    private File file = new File();
    
    @Data
    public static class Jwt {
        private String secret;
        private long expiration;
    }
    
    @Data
    public static class File {
        private String uploadDir;
        private String maxSize;
    }
}

 

다른 클래스에서 사용하기

1.로그로 확인하는방법

더보기
@Service
@Slf4j  // Lombok 로깅 어노테이션
public class JwtService {
    
    private final AppProperties appProperties;
    
    public JwtService(AppProperties appProperties) {
        this.appProperties = appProperties;
    }
    
    @PostConstruct  // 스프링 컨테이너가 빈을 생성한 후 자동 실행
    public void logConfigInfo() {
        // 애플리케이션 시작할 때 설정값 로그로 출력
        log.info("=== JWT 설정 정보 ===");
        log.info("만료시간: {}ms ({}시간)", 
                appProperties.getJwt().getExpiration(),
                appProperties.getJwt().getExpiration() / (1000 * 60 * 60));
        log.info("Secret 길이: {}자", appProperties.getJwt().getSecret().length());
        
        log.info("=== 파일 설정 정보 ===");
        log.info("업로드 디렉토리: {}", appProperties.getFile().getUploadDir());
        log.info("최대 파일 크기: {}", appProperties.getFile().getMaxSize());
    }
    
    // 실제 토큰 생성 메서드
    public String generateToken(String username) {
        // ... JWT 생성 로직
    }
}

2. @Value 주입확인방법

더보기
@Component
@Slf4j
public class ConfigValidator {
    
    // @Value로 직접 주입받기
    @Value("${app.jwt.secret}")
    private String jwtSecret;
    
    @Value("${app.jwt.expiration}")
    private long jwtExpiration;
    
    @Value("${app.file.upload-dir}")
    private String uploadDir;
    
    @Value("${app.file.max-size}")
    private String maxFileSize;
    
    // 환경변수도 직접 주입 가능
    @Value("${JWT_SECRET:기본값없음}")
    private String jwtSecretFromEnv;
    
    @PostConstruct
    public void validateAndLogConfig() {
        log.info("=== @Value로 주입된 설정값 확인 ===");
        
        // 설정값 검증
        if (jwtSecret == null || jwtSecret.length() < 10) {
            log.error("JWT Secret이 너무 짧습니다! 현재 길이: {}", jwtSecret.length());
            throw new IllegalStateException("JWT 설정 오류");
        }
        
        if (jwtExpiration <= 0) {
            log.error("JWT 만료시간이 잘못되었습니다: {}", jwtExpiration);
            throw new IllegalStateException("JWT 만료시간 설정 오류");
        }
        
        // 로그로 확인
        log.info("JWT Secret 길이: {}자", jwtSecret.length());
        log.info("JWT 만료시간: {}ms", jwtExpiration);
        log.info("업로드 디렉토리: {}", uploadDir);
        log.info("최대 파일 크기: {}", maxFileSize);
        log.info("환경변수에서 가져온 JWT Secret: {}", 
                jwtSecretFromEnv.equals("기본값없음") ? "설정안됨" : "설정됨");
        
        log.info("설정 검증 완료!");
    }
}

 

 


 

8. 주의사항과 권장사항

8-1. ❌ 피해야 할 것들

  • 민감한 정보 하드코딩
    • 나쁜 예
      spring: datasource: password: myRealPassword123
  • 너무 깊은 중첩
    • 과도한 중첩은 가독성을 해침
      app: config: database: connection: pool: settings: max: 10

8-2. ✅ 권장사항

  • 환경 변수 활용
  • spring: datasource: password: ${DB_PASSWORD}
  • 적절한 기본값 설정
  • server: port: ${PORT:8080}
  • 프로필별 파일 분리
    • 환경별 설정은 별도 파일로 관리
    • 공통 설정만 메인 파일에 두기

 

 

 


 

 

마무리

application.yml 설정 파일은 처음에는 복잡해 보일 수 있다.

프로젝트를 진행하면서 점진적으로 필요한 설정들을 추가해나가면 된다. 괜히 모르는거 블로그에서 이것저것 퍼오다가 뭐가잘못된지 몰라서 큰일나지말자..

가장 중요한 것은 민감한 정보는 절대 하드코딩하지 않고!!  환경별로 적절한 설정을 분리!! 모르는건 쓰지말자!! 

 

 

 


 

참고 자료

  • Spring Boot 공식 문서 - External Configuration
  • Baeldung - Spring Boot YAML vs Properties
  • Spring Boot Configuration Properties

'공부일기.. > Spring' 카테고리의 다른 글

[spring] 언제! 리팩토링해야 할까? 실전 가이드- 설계원칙 위반 (1/3)  (0) 2025.10.03
[Spring] Spring Boot MySQL 설정 (커넥션 풀, OSIV, SQL 로깅)  (0) 2025.09.18
[Spring-legacy] 이거 @RequestBody Map으로 받아도 되나요?  (1) 2025.08.27
[Redis] Redis 동작원리 : 속도 빠른이유  (4) 2025.08.21
Redis 활용시 직렬화/역직렬화를 해야하는 이유 (ObjectMapper)  (4) 2025.08.17
'공부일기../Spring' 카테고리의 다른 글
  • [spring] 언제! 리팩토링해야 할까? 실전 가이드- 설계원칙 위반 (1/3)
  • [Spring] Spring Boot MySQL 설정 (커넥션 풀, OSIV, SQL 로깅)
  • [Spring-legacy] 이거 @RequestBody Map으로 받아도 되나요?
  • [Redis] Redis 동작원리 : 속도 빠른이유
s0-0mzzang
s0-0mzzang
공부한것을 기록합니다...
  • s0-0mzzang
    승민이의..개발일기..🐰
    s0-0mzzang
  • 전체
    오늘
    어제
    • 전체~ (108)
      • 마음가짐..! (10)
      • 공부일기.. (76)
        • weekly-log (6)
        • Spring (19)
        • Java (18)
        • DataBase (10)
        • git (2)
        • JPA (6)
        • kafka (1)
        • Backend Architecture (3)
        • Troubleshooting (삽질..ㅋ) (2)
        • Cloud (1)
        • Docker (2)
        • 알고리즘 (1)
        • 리액트 (2)
        • Infra (3)
      • 하루일기.. (22)
        • 그림일기 (8)
        • 생각일기 (14)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

    • 깃허브
  • 공지사항

  • 인기 글

  • 태그

    인프라 기초
    BufferedReader
    항해99
    Paging
    ERD
    swagger
    React
    자바
    StringTokenizer
    리팩토링
    MySQL
    다짐
    spring
    항해플러스
    spring boot
    스프링부트
    ADC 환경
    SpringBoot
    TDD
    JPA
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.3
s0-0mzzang
[Spring Boot] application.yml 설정파일 마스타~~
상단으로

티스토리툴바