
인트로
Spring Boot 프로젝트를 시작하면 가장 먼저 마주치는 파일 중 하나가 바로 `application.yml`이다.
이 설정 파일이 어떻게 애플리케이션 전체를 제어하는지에 대해서 포스팅해보려고한다. 보통 설정파일을 제대로 보려고 하지않았기 때문에 소소한 문제가 생겨도 해결하는데 어려움이 있었다.
오늘은 application.yml의 역할부터 활용법까지 모든 것을 포스팅해보도록하겠다.
1. application.yml이란?
`application.yml`은 Spring Boot 애플리케이션의 설정 정보를 담는 핵심 파일이다.
YAML(YAML Ain't Markup Language) 형식으로 작성되며, 애플리케이션의 다양한 속성과 구성 값을 계층적 구조로 정의할 수 있다.
2. 왜 YAML을 사용할까?


기존의 .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' 카테고리의 다른 글
| [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 |
