≣ 목차
외부설정이란?
외부 설정은 애플리케이션이 실행되거나 빌드될 때 외부에서 설정 값을 주입 받는 있는 기능을 의미합니다. 그렇다면 애플리케이션 실행에 필요한 설정값을 외부에서 어떻게 주입할 수 있는 것일까?
외부 설정은 크게 아래와 같이 4개로 나눌 수 있습니다.
- OS 환경 변수: OS에서 지원하는 외부 설정 , OS에서 사용되는 모든 프로세스에 적용 가능
- 자바 시스템 속성: 자바에서 지원하는 외부 설정, 해당 JVM안에서 사용
- 자바 커맨드 라인 인수: 커맨드 라인에서 실행시 main(args) 메서드에서 사용할 인자
- 외부 파일(설정 데이터): 프로그램 외부의 파일을 읽어 사용 (application.properties)
1. OS 환경 변수
환경 변수(environment variables)는 애플리케이션 외부에서 설정된 값들로, 다른 외부 설정과 비교해서 사용 범위가 가장 넓습니다.
조회 방법
- 윈도우 OS: set
- MAC, 리눅스 OS: printenv
@Slf4j
public class OsEnv {
public static void main(String[] args) {
Map<String, String> envMap = System.getenv();
for (String key : envMap.keySet()) {
log.info("env {}={}", key, System.getenv(key));
}
//DBURL = dev.db.com 개발 서버
//DBURL = prod.db.com 운영 서버로 설정
String dburl = System.getenv("DBURL");
// 동일한 환경 변수로 데이터베이스 접근 URL를 OS에 따라 다르게 가져올 수 있습니다.
}
}
2. 자바 시스템 속성
자바 시스템 속성(Java System properties)은 실행한 JVM 안에서 접근 가능한 외부 설정입니다. 그리고 자바가 내부 에서 미리 설정해두고 사용하는 속성들도 존재합니다. 이때 -D명령어를 사용하여 시스템 속성을 설정할 수 있습니다.
2-1 JAR 파일 실행 명령어
java -DmyProperty=value -jar myapp.jar
myProperty라는 key로 값을 설정하여 애플리케이션에서 사용할 수 있습니다.
2-2 IDE에서 설정 방법(인텔리제이)
Edit Configurations를 클릭
2-1. Modify options를 선택
2-2. Add VM options를 선택
2-3. VM options에 다음을 추가
예를 들어, 다음과 같은 형식으로 전달할 수 있습니다.
-Durl=dev.db -Dusername=username_peel -Dpassword=pw_qwer
2-3 자바 코드로 설정
자바 코드로 자바 시스템 속성을 설정할 수 있지만, 외부에서 설정을 분리하는 효과는 없습니다.
설정: System.setProperty("property_key", "property-value");
조회: String propertyKey = System.getProperty("property_key");
3. 커맨드 라인 인수
커맨드 라인 인수(Command line arguments)는 애플리케이션 실행 시점에 외부 설정값을 main(args) 메서드의 args 파라미터로 전달하는 방법입니다.이 인수는 key=value 형식이 아닌 문자 그대로 전달되기 때문에, 실제로 사용할 때는 종종 Map과 같은 형식으로 변환해야 하는 경우가 많습니다. 스프링 부트에서는 이러한 문제를 해결하기 위해 커맨드 라인 옵션 인수 기능을 도입하였습니다.
3-1 JAR 파일 실행 명령어
java -jar app.jar dataA dataB
- 커맨드 라인에 전달하는 값은 형식이 없고, 단순히 띄어쓰기로 구분합니다.
- aaa bbb [aaa, bbb] 값 2개
- hello world [hello, world] 값 2개
- "hello world" [hello world] (공백을 연결하려면 " 를 사용하면 된다.) 값 1개
- test_key=test_value [ test_key = test_value ] 값 1개
3-2 IDE에서 설정 방법(인텔리제이)
Edit Configurations를 들어갑니다. (2-2 방법 참고)
- Program arguments에 값을 입력하면 됩니다.
- 커맨드 라인 인수는 공백(space)으로 구분
3-3 커맨드 라인 옵션 인수
Spring Boot는 커맨드 옵션 인수를 사용하여 설정 값을 key=value 형식으로 전달할 수 있도록 지원합니다. --key=value 형식으로 인수를 전달함으로써 환경 설정이나 사용자 지정 값을 손쉽게 설정할 수 있습니다.
예를 들어, 다음과 같이 여러 개의 인수를 key=value 형식으로 전달할 수 있습니다.
--username=qwer--username=asdf
인수 값 설정 (2-2 방법 참조)
@Slf4j
public class CommandLine {
public static void main(String[] args) {
ApplicationArguments appArgs = new DefaultApplicationArguments(args);
log.info("SourceArgs = {}", List.of(appArgs.getSourceArgs()));
log.info("NonOptionArgs = {}", appArgs.getNonOptionArgs());
log.info("OptionNames = {}", appArgs.getOptionNames());
Set<String> optionNames = appArgs.getOptionNames();
for (String optionName : optionNames) {
log.info("option args {}={}", optionName, appArgs.getOptionValues(optionName));
}
List<String> url = appArgs.getOptionValues("url");
List<String> username = appArgs.getOptionValues("username");
List<String> password = appArgs.getOptionValues("password");
List<String> mode = appArgs.getOptionValues("mode");
log.info("url={}", url);
log.info("username={}", username);
log.info("password={}", password);
log.info("mode={}", mode);
}
}
- DefaultApplicationArguments은 Spring Boot에서 커맨드 라인 인수를 처리하기 위한 클래스이며, ApplicationArguments 인터페이스의 구현체입니다.
- getSourceArgs(): 애플리케이션에 전달된 모든 인수를 배열 형태로 반환
- getNonOptionArgs(): 커맨드 라인 인수가 아닌 일반 인수(비옵션 인수) 목록을 반환
- getOptionNames(): 커맨드 라인 인수만 반환
결과
외부 설정 일관성 문제
위에 방법들을 살펴보면, 외부 설정 값을 가져오는 방식이 각각 다르다는 것을 알 수 있습니다. 예를 들어, 처음에는 OS 환경 변수를 사용해 외부 설정 값을 설정했지만, 나중에 자바 시스템 속성으로 변경해야 하는 상황이 발생할 수 있습니다. 이 경우, 외부 설정 값을 읽어오는 코드를 모두 수정해야 합니다. 이러한 문제를 해결하기 위해서는 추상화 작업이 필요하지만 스프링은 이미 Environment 와 PropertySource으로 추상화해 해당 문제를 해결했습니다.
참고
[1] 스프링 부트 핵심 원리와 활용 - 김영한
'Spring' 카테고리의 다른 글
[Spring Boot] 다양한 외부 설정 방법 #4 - @Profile (1) | 2024.10.15 |
---|---|
[Spring Boot] 다양한 외부 설정 방법 #2 - Environment (2) | 2024.10.13 |
[Sprign Boot] Auto Configuration 정리 - @Conditaional (2) | 2024.10.10 |
[Spring Boot + Java] JAR와 WAR 간단 정리 (1) | 2024.10.06 |
[Spring] Spring AOP의 한계 (0) | 2024.10.04 |