✔️ 외부 설정
하나의 애플리케이션을 여러 다른 환경에 적용
- 개발 환경 : 개발 서버, 개발 DB 사용
- 운영 환경 : 운영 서버, 운영 DB 사용
개발, 운영에 따라 환경 설정을 다르게 하여 빌드하는 것은 비효율적이다.
따라서 우선 빌드를 하고 배포 후 실행 시점에 외부 설정을 주입하는 것이다.
유지보수하기 좋은 애플리케이션 개발의 가장 기본적인 원칙
변하는 것과 변하지 않은 것을 분리
외부 설정 사용 방법
4가지 방법이 있다.
- OS 환경 변수
- 자바 시스템 속성
- 자바 커맨드 라인 인수
- 외부 파일(설정 데이터)
1. OS 환경 변수
System.getenv();
전체 OS 환경 변수를 MAP으로 조회 가능
단, 다른 프로그램에서도 사용 가능
2. 자바 시스템 속성
java -Durl=devdb -Dusername=dev_user -Dpassword=dev_pw -jar app.jar
-D VM 옵션을 통해 key=value 형식을 주면 된다.
IDE에서도 VM 옵션을 키고 -D key=value 형식을 주면 적용가
Properties properties = System.getProperties();
for (Object key : properties.keySet()) {
System.getProperty(String.valueOf(key));
}
Properties는 Map과 유사한 key=value 형식
System.getProperty(key)로 속성값 조회
3. 커맨드 라인 인수
java -jar app.jar dataA dataB
항상 보던 main 함수의 인수(String[] args)로 들어온다.
key=value로는 직접 파싱해야 하며, 공백으로 구분한다. (공백 연결하고 싶으면 ""안에 하나의 문자열로)
IDE에서 실행시 Program arguments로 커맨드 라인을 입력할 수 있다.
없다면 Modify options에서 추가
3-1. 커맨드 라인 옵션 인수
커맨드 라인 인수를 key=value 형식으로 구분해주는 스프링의 표준 방식
--key=value --key=vlaue2
스프링은 커맨드 라인에 -(dash) 2개(--)를 연결해서 시작하면 key=value 형식으로 정함 (커맨드 라인 옵션 인수)
--key=value --key=value2 : 하나의 키에 여러 값 지정 가능
public static void main(String[] args) {
ApplicationArguments arguments = new DefaultApplicationArguments(args);
Set<String> optionNames = arguments.getOptionNames();
log.info("SourceArgs {}", List.of(arguments.getSourceArgs())); // 전체 인수
log.info("NonOptionArgs {}", List.of(arguments.getNonOptionArgs())); // -- 옵션인수가 아닌 인수
for (String optionName : optionNames) {
log.info("option args {}={}", optionName, arguments.getOptionValues(optionName));
}
스프링이 제공하는 ApplicationArguments 인터페이스와 DefaultApplicationArguments 구현체를 사용
✔️ 커맨드 라인 옵션 인수와 스프링 부트
스프링 부트는 커맨드 라인 포함 커맨드 라인 옵션 인수를 활용할 수 있는 ApplicationArguments를 스프링 빈으로 등록해둠
따라서 빈 등록후 주입받으면 된다.
@Component
public class CommandLineBean {
private final ApplicationArguments arguments;
public CommandLineBean(ApplicationArguments arguments) {
this.arguments = arguments;
}
스프링 통합
스프링은 PropertySource 라는 추상 클래스를 제공, 각각 외부 설정을 조회하는 XxxPropertySource 구현체 만듦
스프링은 로딩 시점에 필요한 PropertySource 생성, Environment에서 사용할 수 있게 연결
Environment
특정 외부 설정에 종속되지 않고, 일관성 있게 key=value 형식의 외부 설정 접근 가능
private final Environment env;
public EnvironmentCheck(Environment env) {
this.env = env;
}
env.getProperty(key); // 외부 설정 접근
✔️ 설정 데이터
외부파일
설정 값을 파일로 관리
애플리케이션 로딩 시점에 해당 파일을 읽어들임
build/libs 에 application.properties 파일 생성(설정 파일)
jar 실행하면 적용됨
단, 설정 파일을 외부에서 관리하는 것은 상당히 번거로움 (서버가 많으면 각각 다 따로 적용)
따라서 설정 파일을 프로젝트 내부에 포함해서 관리한다.
✔️ 내부 파일 분리
개발용 설정 파일: application-dev.properties
운영용 설정 파일: application-prod.properties
빌드 시점에 이 2개를 모두 포함해서 빌드
외부 설정으로 넘어온 프로필 값이 dev면 개발용 설정 파일을 읽고, prod면 운영용을 읽는다.
프로필
스프링은 프로필이라는 개념 지원
프로필에 따라 다음과 같은 규칙으로 해당 프로필에 맞는 내부파일(설정 데이터)을 조회
application-{profile}.properties
프로필 활성화
spring.profiles.active=dev
dev 프로필 활성화
실행
IDE에서 커맨드 라인 옵션 인수 실행
--spring.profiles.active=dev
IDE에서 자바 시스템 속성 실행
-Dspring..profiles.active=dev
Jar 실행
// 빌드 한 후
java -Dspring.profiles.active=dev -jar app.jar
java -jar app.jar --spring.profiles.active=dev
✔️ 내부 파일 합체
사실상 굳이 2개의 설정파일을 나눌 필요가 없다.
하나의 설정 파일에 프로필별로 논리적 영역을 나누면 된다.
url=local.db.com
username1=local_user
password=local_pw
#---
spring.config.activate.on-profile=dev
url=dev.db.com
username1=dev_user
password=dev_pw
#---
spring.config.activate.on-profile=prod
url=prod.db.com
username1=prod_user
password=prod_pw
application.properties 논리 영역 나누는 방법
- application.properties : #--- , !---
- application.yml : ---
실행은 프로필 실행에 나온거로 하면 된다.
우선순위
유연한것, 자세한 것이 우선순위를 가짐
설정데이터는 프로필 값이 존재하지 않거나 설정파일에 없으면 default 프로필이 적용된다.
또한 스프링은 문서를 위에서 아래로 순서대로 읽는다.
즉 아래를 예시로 본다면
url=local.db.com #프로필이 없으므로 해당 영역을 먼저 적용
username1=local_user
password=local_pw
#---
spring.config.activate.on-profile=dev # dev 프로필을 줬다면 해당 영역 값으로 덮어씀
url=dev.db.com
username1=dev_user
password=dev_pw
#---
spring.config.activate.on-profile=prod # prod 프로필을 줬다면 해당 영역 값으로 덮어씀
url=prod.db.com
username1=prod_user
password=prod_pw
#---
url=fake.db.com # 프로필이 없으므로 항상 적용
전체 우선순위
- 설정 데이터
- OS 환경 변수
- 자바 시스템 속성 (JVM)
- 커맨드 라인 옵션 인수 (main args에서만 사용)
- @TestPropertySource (테스트에서 사용)
설정 데이터 우선순위 (application.properties)
- jar 내부 설정파일
- jar 내부 프로필 적용 파일 (-{profile}.properties
- jar 외부 설정 파일
- jar 외부 프로필 적용 파
🔖 학습내용 출처
'Back-End > Spring Advance & Boot' 카테고리의 다른 글
스프링 부트 - 외부 설정과 프로필2 (0) | 2025.01.21 |
---|---|
스프링 부트 - 자동 구성 (0) | 2024.11.27 |
스프링 부트 - 부트와 내장 톰캣 (0) | 2024.11.19 |
스프링 부트 - 웹 서버와 서블릿 컨테이너 (2) | 2024.11.15 |
스프링 고급편 - 실무 주의사항 (내부호출, 기술과 한계) (1) | 2024.11.13 |