외부 설정 - 2
커맨드 라인 인수
커맨드 라인 인수 (Command line arguments) 는 애플리케이션 실행 시점에 외부 설정값을 main(args) 메서드의 args 파라미터로 전달하는 방법
사용
- java -jar app.jar dataA dataB
- 필요한 데이터를 마지막 위치에 스페이스로 구분해서 전달
- dataA, dataB 2개의 문자가 args 에 전달됨


커맨드 라인 인수는 공백 (space)로 구분
CommandLineV1 - arg dataA
CommandLineV1 - arg dataB
보통 key=value 형식으로 데이터를 받는것이 편리함
커맨드 라인 인수를 다음과 같이 입력
url=devdb username=dev_user password=dev_pw

- 커맨드 라인 인수는 key=value 형식이 아닌 문자열 형식
- 이 경우 개발자가 = 를 기준으로 직접 데이터를 파싱해서 key=value 형식에 맞게 분리해야함
커맨드 라인 옵션 인수
일반적인 커맨드 라인 인수
단순 띄어쓰기로 구분
- aaa bbb ➡️ [aaa, bbb] 2개
- hello world ➡️ [hello, world] 2개
- "hello world" ➡️ [hello world] (공백 연결시 " 사용) 1개
- key=value ➡️ [key=value] 1개
커맨드 라인 옵션 인수 (command line option arguments)
key=value 로 구분하는 방법이 필요함
스프링에서는 커맨드 라인 인수를 편리하게 사용할 수 있도록 표준 방식을 정의함, 그게 커맨드 라인 옵션 인수임
커맨드 라인에 - (dash) 2개를 -- 연결해서 시작하면 key=value 형식으로 정함, 이것을 커맨드 라인 옵션 인수라고 함
- --key=value 형식으로 사용
- --username=userA --username=userB ➡️ 하나의 키에 여러 값도 지정 가능
src/test 하위

스프링이 제공하는 ApplicationArguments 인터페이스와 DefaultApplicationArguments 구현체를 사용하면 커맨드 라인 옵션 인수를 규격대로 파싱해서 편리하게 사용 가능
실행


- arg : 커맨드 라인의 입력 결과를 그대로 출력
- SourceArgs : 커맨드 라인 인수 전부를 출력
- NonOptionArgs = [mode=on] : 옵션 인수가 아님. key=value 형식으로 파싱되지 않음. -- 를 앞에 사용하지 않음
- OptionNames = [password, url, username] : key=value 형식으로 사용되는 옵션 인수. -- 를 앞에 사용
- url , username , password 는옵션 인수이므로 appArgs.getOptionValues(key) 로 조회 가능
- mode 는 옵션 인수가 아니므로 appArgs.getOptionValues(key) 로 조회 할 수 없음. 결과는 null
커맨드 라인 옵션 인수와 스프링 부트
스프링 부트는 커맨드 라인 옵션 인수를 활용할 수 있는 ApplicationArguments 를 스프링 빈으로 등록 ➡️ 입력한 커맨드 라인 저장 ➡️ 해당 빈을 주입 받으면 커맨드 라인으로 입력한 값은 어디서든 사용 가능
src/main 하위

입력한 커맨드 라인 인수, 커맨드 라인 옵션 인수 확인

스프링 통합
커맨드 라인 옵션 인수, 자바 시스템 속성, OS 환경 변수는 모두 외부설정을 key=value 형식으로 사용할 수 있는 방법임
어디에 있는 외부 설정값을 읽어야 하는지에 따라 각각 읽는 방법이 다르다는 단점이 있음
외부 설정값의 위치 상관없이 일관성 있고, 편리하게 key=value 형식의 외부 설정값을 읽을 수 있으면 개발자 입장에서 더편리하고 또 외부 설정값을 설정하는 방법도 더 유연해 질 수 있음
스프링은 이 문제를 Environment 와 PropertySource 라는 추상화를 통해서 해결
스프링의 외부 설정 통합

PropertySource
- org.springframework.core.env.PropertySource
- 스프링은 PropertySource 라는추상 클래스를 제공, 각각의 외부 설정을 조회하는 XxxPropertySource 구현체를 만들어둠
- CommandLinePropertySource
- SystemEnvironmentPropertySource
- 스프링은 로딩시점에 필요한 PropertySource 들을 생성, Environment 에서 사용할 수 있게 연결함
Environment
- org.springframework.core.env.Environment
- Environment 를 통해 특정 외부 설정에 종속되지 않고, 일관성있게 key=value 형식의 외부 설정에 접근 가능
- environment.getProperty(key) 를 통해서 값 조회 가능
- Environment 는 내부에서 여러 과정을 거쳐서 PropertySource 들에 접근
- 같은 값이 있을 경우를 대비해 스프링은 미리 우선순위를 정해둠
- 모든 외부설정은 Environment 를 통해서 조회하면 됨
src/main 하위

커맨드 라인 옵션 인수와 자바 시스템 속성 실행
- --url=devdb --username=dev_user --password=dev_pw
- -Durl=devdb -Dusername=dev_user -Dpassword=dev_pw

우선 순위
우선 순위는 2가지만 기억하면 됨
- 더 유연한 것이 우선권을 가짐. (변경하기 어려운 파일보다 실행시 원하는 값을 줄 수있는 자바 시스템 속성이 더 우선권을 가짐)
- 범위가 넒은 것보다 좁은것이 우선권을 가진다. (자바 시스템 속성은 해당 JVM 안에서 모두 접근할 수 있음. 반면에 커맨드 라인 옵션 인수는 main 의 arg를 통해 들어오기 때문에 접근 범위가 더 좁음)
feat. 스프링부트 - 핵심 원리와 활용 (김영한)
'다시 웹, 백엔드로 > 스프링' 카테고리의 다른 글
우선순위 (0) | 2023.09.05 |
---|---|
설정 데이터 (0) | 2023.09.04 |
외부 설정 - 1 (0) | 2023.09.01 |
자동 구성 라이브러리 만들기/사용 (0) | 2023.08.31 |
순수 라이브러리 사용 (0) | 2023.08.30 |