Spring Boot 기본 설정 가이드 - Configuration, DI, Profile, Devtools
Spring Boot 애플리케이션을 개발할 때 가장 기본이 되는 설정 방법들을 정리했습니다. Configuration Properties부터 의존성 주입, Profile 관리, 그리고 개발 생산성을 높이는 Devtools까지 살펴보겠습니다.
Configuration Properties
Spring Boot에서는 @ConfigurationProperties 어노테이션을 사용하여 타입 안전한 설정 관리가 가능합니다.
기본 사용법
@ConfigurationProperties("basic")
class BasicConfiguration {
boolean value;
}
application.properties 파일에 다음과 같이 설정합니다:
basic.value=true
설정 클래스를 사용하려면 @Autowired로 주입받습니다:
@Autowired
BasicConfiguration configuration;
고급 Configuration 클래스
리스트나 복잡한 구조의 설정도 가능합니다:
@Configuration
@EnableConfigurationProperties
@ConfigurationProperties("aa")
class Config {
lateinit var email: String
var jiraProjects: List<String> = ArrayList<String>()
}
application.properties:
aa.email=example@example.com
email[0]=first@example.com
email[1]=second@example.com
application.yml에서 리스트 설정:
jiraProjects:
- PROJECT1
- PROJECT2
- PROJECT3
Dependency Injection (의존성 주입)
Spring의 핵심 기능 중 하나인 의존성 주입은 @Service, @Component, @Repository, @Controller 등의 어노테이션을 통해 빈을 등록하고 사용합니다.
빈 등록
@Service
class LoginService {}
// 또는
@Component
class LoginService {}
빈 주입
@Autowired
LoginService loginService;
Component Scan
@SpringBootApplication 어노테이션에는 @ComponentScan이 포함되어 있어 자동으로 컴포넌트를 스캔합니다:
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan(excludeFilters = {
@Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class),
@Filter(type = FilterType.CUSTOM, classes = AutoConfigurationExcludeFilter.class)
})
public @interface SpringBootApplication {
특정 패키지만 스캔하고 싶은 경우:
@SpringBootApplication
@ComponentScan("com.example.web.home")
class WebApplication
Profile
Spring Profile을 사용하면 환경별로 다른 설정을 적용할 수 있습니다. 개발(dev), 스테이징(stage), 운영(prod) 환경에 맞는 설정을 분리하여 관리할 수 있습니다.
빈에 Profile 적용
@Profile("prod")
@Bean
public String dummy() {
return "production";
}
공통 설정은 application.properties에, 환경별 설정은 application-{profile}.properties에 작성합니다.
YAML에서 Profile 설정
YAML 파일에서는 ---로 구분하여 여러 프로파일을 정의할 수 있습니다:
spring:
profiles: dev
server:
port: 8080
---
spring:
profiles: prod
server:
port: 80
Profile 실행 방법
Gradle 프로젝트:
IntelliJ에서 Edit Configurations로 active profile 설정하거나, JAR 실행 시:
java -Dspring.profiles.active=localhost -jar myapp-1.0.0.jar
주의:
-D옵션은 반드시-jar앞에 위치해야 합니다.
빌드 시 프로파일 지정:
clean bootJar -b app/build.gradle -Pprofile=dev
Maven 프로젝트:
mvn clean package --activate-profiles development -Dmaven.test.skip=true
다중 Profile 활성화
여러 프로파일을 동시에 활성화할 수 있습니다:
spring.profiles.active=slack,facebook
서비스별로 프로파일 적용:
@Component
@Profile("facebook")
public class FacebookBot extends Bot {}
@Component
@Profile("slack")
public class SlackBot extends Bot {}
Spring Boot Devtools
Devtools는 개발 생산성을 크게 향상시켜주는 도구입니다.
주요 기능
- 코드 변경 후 컴파일만 하면 실행 중인 애플리케이션에 자동 반영
- 빠른 애플리케이션 재시작
- 라이브 리로드 지원
사용 시 주의사항
- Gradle이나 Maven
pom.xml파일이 변경된 경우에는 애플리케이션을 재시작해야 합니다. - 프로덕션 환경에서는 자동으로 비활성화됩니다.
의존성 추가
Gradle:
developmentOnly 'org.springframework.boot:spring-boot-devtools'
Maven:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
Property 참조
설정 파일 내에서 다른 프로퍼티를 참조할 수 있습니다:
propertyA=value
propertyB=${propertyA} # propertyA의 값을 사용
외부 설정 파일 우선순위
Spring Boot는 다양한 위치에서 설정을 읽으며, 다음 순서로 우선순위가 적용됩니다 (아래로 갈수록 높음):
application.properties(클래스패스)application-{profile}.properties(클래스패스)application.properties(JAR 파일 외부)application-{profile}.properties(JAR 파일 외부)- 환경 변수
- 커맨드 라인 인자
이 우선순위를 활용하면 JAR에 기본 설정을 포함하면서도 배포 환경에서 외부 설정 파일로 유연하게 오버라이드할 수 있습니다.
@Value 어노테이션
간단한 설정값을 주입받을 때는 @Value 어노테이션을 사용할 수 있습니다:
@Value("${server.port:8080}")
private int serverPort;
@Value("${app.name}")
private String appName;
@Value("${app.features.enabled:false}")
private boolean featureEnabled;
콜론(:) 뒤에 기본값을 지정할 수 있어 설정이 누락되었을 때 안전하게 동작합니다. 다만 설정값이 많아지면 @ConfigurationProperties가 더 관리하기 편리합니다.
Conditional Bean 등록
특정 조건에서만 빈을 등록하도록 제어할 수 있습니다:
@Bean
@ConditionalOnProperty(name = "cache.enabled", havingValue = "true")
public CacheManager cacheManager() {
return new ConcurrentMapCacheManager();
}
@Bean
@ConditionalOnMissingBean(DataSource.class)
public DataSource defaultDataSource() {
// 기본 DataSource 생성
}
주요 Conditional 어노테이션:
| 어노테이션 | 조건 |
|---|---|
@ConditionalOnProperty |
특정 프로퍼티 값에 따라 |
@ConditionalOnMissingBean |
해당 빈이 없을 때만 |
@ConditionalOnClass |
특정 클래스가 클래스패스에 있을 때 |
@ConditionalOnProfile |
특정 프로파일이 활성화되었을 때 |
환경 변수를 이용한 설정
Spring Boot는 환경 변수를 자동으로 프로퍼티로 변환합니다. 이를 통해 Docker 컨테이너나 클라우드 환경에서 설정을 유연하게 관리할 수 있습니다.
환경 변수 바인딩 규칙
Spring Boot는 환경 변수를 프로퍼티 이름으로 변환할 때 Relaxed Binding을 적용합니다:
# 환경 변수 → 프로퍼티 매핑
SPRING_DATASOURCE_URL → spring.datasource.url
SERVER_PORT → server.port
MY_APP_FEATURE_ENABLED → my.app.feature-enabled
Docker에서의 활용
FROM openjdk:17-jdk-slim
COPY target/myapp.jar app.jar
ENTRYPOINT ["java", "-jar", "app.jar"]
# docker-compose.yml
version: '3.8'
services:
app:
build: .
environment:
- SPRING_PROFILES_ACTIVE=prod
- SPRING_DATASOURCE_URL=jdbc:mysql://db:3306/mydb
- SPRING_DATASOURCE_USERNAME=root
- SPRING_DATASOURCE_PASSWORD=secret
ports:
- "8080:8080"
설정 암호화 (Jasypt)
민감한 설정값(비밀번호, API 키 등)을 평문으로 설정 파일에 저장하는 것은 보안 위험이 있습니다. Jasypt 라이브러리를 사용하면 설정값을 암호화할 수 있습니다.
의존성 추가
implementation 'com.github.ulisesbocchio:jasypt-spring-boot-starter:3.0.5'
암호화된 설정 사용
# ENC()로 감싸면 자동으로 복호화됩니다
spring.datasource.password=ENC(암호화된문자열)
jasypt.encryptor.password=${JASYPT_PASSWORD} # 환경 변수에서 복호화 키 가져오기
설정 파일 분리 전략
대규모 프로젝트에서는 설정 파일을 목적별로 분리하는 것이 관리에 용이합니다.
기능별 분리
application.yml # 공통 설정
application-db.yml # 데이터베이스 설정
application-cache.yml # 캐시 설정
application-security.yml # 보안 설정
application-prod.yml # 프로덕션 환경
application-dev.yml # 개발 환경
spring.config.import (Spring Boot 2.4+)
# application.yml
spring:
config:
import:
- application-db.yml
- application-cache.yml
Profile Group (Spring Boot 2.4+)
여러 프로파일을 그룹으로 묶어 한 번에 활성화할 수 있습니다:
spring:
profiles:
group:
prod: db-prod, cache-prod, security-prod
dev: db-dev, cache-dev, security-dev
-Dspring.profiles.active=prod만 지정하면 db-prod, cache-prod, security-prod가 모두 활성화됩니다.
자주 발생하는 설정 문제와 해결
1. 프로퍼티 바인딩 실패
@ConfigurationProperties 사용 시 타입 불일치로 바인딩이 실패하는 경우:
// 문제: String을 boolean으로 바인딩
// application.properties에 feature.enabled=yes (boolean이 아님)
// 해결: Spring Boot는 yes/no, on/off, 1/0을 boolean으로 자동 변환합니다
feature.enabled=yes // true로 변환됨
2. Profile이 적용되지 않는 경우
# 확인 방법: 시작 시 로그에서 Active profiles 확인
# The following profiles are active: dev
# 환경 변수와 커맨드 라인에서 동시에 지정하면 커맨드 라인이 우선
java -Dspring.profiles.active=prod -jar app.jar
3. 설정 파일 인코딩 문제
한글이 포함된 properties 파일은 인코딩 문제가 발생할 수 있습니다. YAML 파일은 기본적으로 UTF-8이므로 한글 사용이 자유롭습니다.
# properties 파일에서 한글 사용 (유니코드 이스케이프 필요)
app.message=\uD55C\uAD6D\uC5B4
# YAML에서는 직접 사용 가능
app:
message: 한국어
결론
Spring Boot의 설정 기능들을 잘 활용하면 환경별로 유연하게 대응할 수 있고, 개발 생산성도 높일 수 있습니다. 특히 @ConfigurationProperties를 사용한 타입 안전한 설정 관리와 Profile을 통한 환경 분리는 실무에서 필수적인 기능입니다. 설정의 우선순위를 이해하고, Conditional Bean 등록을 적절히 활용하면 복잡한 환경에서도 깔끔한 설정 구조를 유지할 수 있습니다.
Comments