안녕하세요. stark입니다!
스프링부트는 애플리케이션의 설정을 관리하기 위해 프로퍼티 파일(properties 파일) 또는 YAML 파일을 주로 사용합니다. 이러한 설정 파일들은 애플리케이션이 실행될 때 특정 규칙과 우선순위에 따라 로드되며, 다양한 환경에서 유연하게 동작할 수 있도록 설계되어 있습니다. 이번 글에서는 프로퍼티 파일이 어떤 규칙으로 로드되는지, 이를 어떻게 활용할 수 있는지를 상세히 알아봅시다.
1. 기본적인 프로퍼티 파일 로드 규칙
스프링부트 애플리케이션은 실행 시, 특정 경로에서 설정 파일을 자동으로 탐지합니다. 가장 기본적으로 사용되는 파일은 application.properties 또는 application.yml이며, 다음과 같은 경로에서 찾습니다.
1. classpath 경로
- 일반적으로 src/main/resources 디렉토리 아래에 위치한 파일입니다.
- 이 디렉토리는 빌드 시 자동으로 포함되므로, 별도의 작업 없이 기본 설정 파일을 사용할 수 있습니다.
2. 외부 디렉토리
- 실행 시 명시적으로 제공된 경로에서 설정 파일을 로드할 수 있습니다.
- 예를 들어, 파일을 /opt/config/ 경로에 배치하고 이를 지정할 수 있습니다.
스프링부트는 위 경로들을 순서대로 탐색하여 설정 파일을 로드하며, 다음과 같은 우선순위를 따릅니다.
우선순위 예시 (높은 우선순위 순):
1. 명령줄에서 지정된 `--spring.config.location` 옵션
2. `classpath:/application.properties` 또는 `classpath:/application.yml`
3. 외부 설정 파일
- 예를 들어, 명령줄에서 파일 경로를 명시한 경우, 해당 파일이 가장 높은 우선순위를 가집니다.
명령줄에서 파일 경로를 명시한다는 의미를 알아봅시다.
- 스프링부트는 애플리케이션 실행 시 설정 파일의 경로를 명령줄 인수로 전달받아 사용할 수 있습니다. 이를 통해 애플리케이션이 기본 경로 대신 지정된 외부 설정 파일을 우선적으로 로드하도록 할 수 있습니다.
// properties
java -jar app.jar --spring.config.location=file:/path/to/config/application.properties
// yaml
java -jar app.jar --spring.config.location=file:/path/to/config/application.yml
- 위 명령어는 /path/to/config/application.properties 또는 .yaml 파일을 설정 파일로 로드하도록 지정합니다.
명령줄에서 설정 파일 경로를 명시하는 방식은 다음과 같은 상황에서 유용합니다.
- 환경별로 서로 다른 설정 파일을 적용해야 하는 경우.
- 컨테이너 또는 외부 배포 환경에서 설정 파일을 관리해야 하는 경우.
- 기본 경로 외부에 저장된 민감한 정보(예: 데이터베이스 비밀번호)를 로드해야 하는 경우.
2. 프로파일(Profile) 기반 설정 관리
스프링부트는 환경별로 다른 설정을 적용할 수 있도록 프로파일(Profile) 기능을 제공합니다. 이를 통해 개발 환경(dev), 테스트 환경(test), 운영 환경(prod) 등 다양한 환경에 따라 별도의 설정 파일을 준비하고 사용할 수 있습니다.
프로파일 파일 구조 알아보기
- 기본 설정 파일
- 모든 환경에 공통적으로 적용되는 설정을 포함합니다.
- 파일명: application.properties 또는 application.yml
- 프로파일별 설정 파일
- 특정 환경에서만 적용되는 설정을 포함합니다.
- 파일명: application-{profile}.properties 또는 application-{profile}.yml
- 예: application-dev.properties (개발 환경), application-prod.yml (운영 환경)
파일 구조 tree (YAML 형식)
src/main/resources
├── application.yml
├── application-dev.yml
└── application-prod.yml
- application.yml (기본 설정)
server:
port: 8080
spring:
datasource:
url: jdbc:mysql://localhost:3306/mydb
username: root
password: rootpass
- application-dev.yml (개발 환경)
server:
port: 8081
spring:
datasource:
url: jdbc:mysql://localhost:3306/devdb
username: devuser
password: devpass
- application-prod.yml (운영 환경)
server:
port: 9090
spring:
datasource:
url: jdbc:mysql://prod-db:3306/proddb
username: produser
password: prodpass
- 이렇게 구성하면, 개발 환경에서는 application-dev.yml 설정이 적용되고, 운영 환경에서는 application-prod.yml 설정이 적용됩니다.
프로파일 활성화 방법
- 프로파일은 애플리케이션 실행 시 활성화해야 적용됩니다. 활성화 방법은 다음과 같습니다.
1. 명령줄에서 지정 (한번 더 설명합니다.)
java -jar app.jar --spring.profiles.active=prod
- 위 명령어는 운영 환경(prod) 프로파일을 활성화합니다.
2. 환경 변수로 지정
export SPRING_PROFILES_ACTIVE=dev
- 이 방법은 CI/CD 파이프라인이나 Docker 컨테이너 환경에서 유용하게 사용할 수 있습니다.
3. 코드에서 지정
@SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication app = new SpringApplication(Application.class);
app.setAdditionalProfiles("test");
app.run(args);
}
}
- 위 코드는 test 프로파일을 활성화합니다.
프로파일 적용 우선순위
- 활성화된 프로파일(dev, prod)에 해당하는 설정 파일이 기본 설정 파일보다 높은 우선순위를 가집니다. 즉, application-prod.properties 파일이 로드되면 application.properties 파일보다 우선순위가 높기에 설정을 덮어씁니다.
3. 다중 소스 설정 병합과 우선순위
스프링부트는 설정 파일을 다양한 소스에서 로드하고 이를 병합합니다. 설정 값이 충돌하는 경우, 우선순위가 높은 설정이 최종적으로 적용됩니다. 아래는 주요 우선순위 규칙입니다.
1. 명령줄 매개변수
- 실행 시 --옵션=값 형태로 제공되는 설정 값입니다.
- 예: --server.port=8081와 같이 설정하면, 다른 모든 설정보다 우선적으로 적용됩니다.
- 주로 배포 환경에서 빠르게 설정 값을 변경하거나, 테스트 시 특정 설정을 적용할 때 유용합니다.
2. SPRING_APPLICATION_JSON
- JSON 형식의 설정 값을 환경 변수 또는 시스템 프로퍼티를 통해 전달할 수 있습니다.
- 예: SPRING_APPLICATION_JSON={"server.port":9090,"spring.datasource.url":"jdbc:mysql://localhost:3306/test"}
- JSON 데이터를 통해 복잡한 설정 값을 한 번에 전달할 수 있어 유연성이 높습니다.
3. 환경 변수와 시스템 프로퍼티
- 운영 체제나 실행 환경에서 제공하는 설정 값입니다.
- 예: export SERVER_PORT=8082 또는 -Dserver.port=8082 형태로 사용됩니다.
- 컨테이너 환경(Docker, Kubernetes 등)에서 주로 활용됩니다.
4. 프로파일별 설정 파일
- application-{profile}.properties 또는 application-{profile}.yml에 정의된 설정입니다.
- 활성화된 프로파일에 따라 해당 파일의 설정 값이 적용됩니다.
- 예: application-prod.yml의 설정이 prod 프로파일 활성화 시 적용됩니다.
5. 기본 설정 파일
- application.properties 또는 application.yml 파일의 설정 값입니다.
- 기본값으로 적용되며, 위 우선순위 항목에서 설정 값이 없을 경우 사용됩니다.
6. 스프링 기본값
- 스프링 프레임워크가 기본적으로 제공하는 설정 값입니다.
- 모든 사용자 지정 설정이 없을 경우 적용됩니다.
- 예: 서버 포트는 명시적으로 설정되지 않은 경우 기본적으로 8080으로 동작합니다.
병합과 우선순위의 실제 동작 예시
- 다음과 같이 여러 설정 파일과 입력값이 있다고 가정합니다.
기본 설정 파일 (application.properties)
server.port=8080
spring.datasource.url=jdbc:mysql://localhost:3306/defaultdb
spring.datasource.username=root
spring.datasource.password=rootpass
프로파일별 설정 파일 (application-prod.properties)
server.port=9090
spring.datasource.url=jdbc:mysql://prod-db:3306/proddb
spring.datasource.username=produser
spring.datasource.password=prodpass
명령줄 매개변수
java -jar app.jar --server.port=7070 --spring.datasource.username=cliuser
병합 결과 살펴보기
- server.port: 명령줄에서 지정된 7070이 가장 높은 우선순위로 적용됩니다.
- spring.datasource.url: 프로파일별 설정 파일(application-prod.properties)에서 지정된 jdbc:mysql://prod-db:3306/proddb가 적용됩니다.
- spring.datasource.username: 명령줄에서 지정된 cliuser가 적용됩니다.
- spring.datasource.password: 프로파일별 설정 파일의 prodpass가 적용됩니다.
server.port=7070
spring.datasource.url=jdbc:mysql://prod-db:3306/proddb
spring.datasource.username=cliuser
spring.datasource.password=prodpass
4. 외부 파일 로드와 커스터마이징
스프링부트는 외부 설정 파일의 로드를 지원합니다. 이를 통해 애플리케이션 코드를 변경하지 않고 설정을 관리할 수 있습니다.
외부 파일 구조 예시
/config
├── common.yml
└── production.yml
- common.yml
logging:
level: INFO
- production.yml
logging:
level: ERROR
- 아래의 명령어는 두 파일을 병합하여 설정을 로드합니다.
java -jar app.jar --spring.config.location=file:/config/common.yml,file:/config/production.yml
5. 테스트 환경에서의 프로파일 사용: @Profile과 @ActiveProfiles
테스트 코드를 작성할 때, 특정 설정이 테스트 환경에서만 활성화되도록 할 수 있습니다. 이를 위해 스프링은 @Profile 어노테이션과 @ActiveProfiles를 제공합니다.
@Profile 사용하기
- @Profile은 특정 프로파일에서만 빈(bean)이 로드되도록 제어하는 데 사용됩니다. 스프링 애플리케이션 컨텍스트가 초기화될 때 활성화된 프로파일(spring.profiles.active)을 확인합니다. 해당 프로파일이 설정 파일이나 코드에서 @Profile에 명시된 프로파일과 일치하면, 빈이 로드됩니다.
@Configuration
@Profile("test")
public class TestConfiguration {
@Bean
public DataSource dataSource() {
return new H2DataSource(); // 테스트용 H2 데이터베이스
}
}
- 위의 코드에서는 spring.profiles.active=test로 설정되었을 때만 TestConfiguration 클래스가 로드됩니다. spring.profiles.active가 prod라면 TestConfiguration은 무시됩니다.
@ActiveProfiles 사용하기
- @ActiveProfiles는 주로 테스트 환경에서 특정 프로파일을 활성화하는 데 사용됩니다. JUnit과 같은 테스트 프레임워크와 함께 사용됩니다. 테스트 실행 시 @ActiveProfiles에 명시된 프로파일이 spring.profiles.active로 설정됩니다. 테스트 컨텍스트가 초기화되면서 해당 프로파일에 따라 적합한 설정이나 빈을 로드합니다.
@ExtendWith(SpringExtension.class)
@ActiveProfiles("test")
@SpringBootTest
public class UserServiceTest {
@Autowired
private UserService userService;
@Test
public void testUserCreation() {
// 테스트 로직
assertNotNull(userService);
}
}
- 위의 코드에서는 @ActiveProfiles("test")로 인해 테스트 컨텍스트가 초기화될 때 test 프로파일이 활성화됩니다. 테스트 코드에서 사용할 빈들은 test 프로파일 기반 설정에 따라 초기화됩니다.
'Spring > Spring 설정' 카테고리의 다른 글
[Spring] 스프링 빈 설정의 진화: XML에서 자바, 그리고 컴포넌트 기반으로 (0) | 2024.08.23 |
---|---|
Gradle: Implementation과 RuntimeOnly의 차이점 및 활용 방법 (0) | 2023.12.11 |
[Spring] Gradle 이해하기 (0) | 2023.11.08 |
[Spring] yml vs properties 설정파일 비교 (1) | 2023.11.08 |
[Spring] Maven이란? (0) | 2023.11.08 |