You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
System.getenv() 를 사용하면 전체 OS 환경 변수를 Map 으로 조회할 수 있다.
System.getenv(key) 를 사용하면 특정 OS 환경 변수의 값을 String 으로 조회할 수 있다.
실행 결과
OS 환경 변수를 설정하고, 필요한 곳에서 System.getenv() 를 사용하면 외부 설정을 사용할 수 있다.
이제 데이터베이스 접근 URL과 같은 정보를 OS 환경 변수에 설정해두고 읽어들이면 된다. 예를 들어서 개발 서버에서는 DBURL=dev.db.com 과 같이 설정하고, 운영 서버에서는 DBURL=prod.db.com 와 같이 설정하는 것이다.
이렇게 하면 System.getenv("DBURL") 을 조회할 때 각각 환경에 따라서 서로 다른 값을 읽게 된다.
하지만 OS 환경 변수는 이 프로그램 뿐만 아니라 다른 프로그램에서도 사용할 수 있다. 쉽게 이야기해서 전역 변수 같은 효과가 있다. 여러 프로그램에서 사용하는 것이 맞을 때도 있지만, 해당 애플리케이션을 사용하는 자바 프로그램 안에서만 사용되는 외부 설정값을 사용하고 싶을 때도 있다. 다음에는 특정 자바 프로그램안에서 사용하는 외부 설정을 알아보자.
외부 설정 - 자바 시스템 속성
자바 시스템 속성(Java System properties)은 실행한 JVM 안에서 접근 가능한 외부 설정이다. 추가로 자바가 내부에서 미리 설정해두고 사용하는 속성들도 있다.
자바 시스템 속성은 다음과 같이 자바 프로그램을 실행할 때 사용한다.
예) java -Durl=dev -jar app.jar
-D VM 옵션을 통해서 key=value 형식을 주면 된다. 이 예제는 url=dev 속성이 추가된다.
스프링이 제공하는 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 이다.
참고
참고로 옵션 인수는 --username=userA --username=userB 처럼 하나의 키에 여러 값을 포함할 수 있기 때문에 appArgs.getOptionValues(key) 의 결과는 리스트( List )를 반환한다.
커맨드 라인 옵션 인수는 자바 언어의 표준 기능이 아니다. 스프링이 편리함을 위해 제공하는 기능이다.
외부 설정 - 커맨드 라인 옵션 인수와 스프링 부트
스프링 부트는 커맨드 라인을 포함해서 커맨드 라인 옵션 인수를 활용할 수 있는 ApplicationArguments 를 스프
링 빈으로 등록해둔다. 그리고 그 안에 입력한 커맨드 라인을 저장해둔다. 그래서 해당 빈을 주입 받으면 커맨드 라인으
로 입력한 값을 어디서든 사용할 수 있다.
지금까지 살펴본, 커맨드 라인 옵션 인수, 자바 시스템 속성, OS 환경변수는 모두 외부 설정을 key=value 형식으로
사용할 수 있는 방법이다. 그런데 이 외부 설정값을 읽어서 사용하는 개발자 입장에서 단순하게 생각해보면, 모두
key=value 형식이고, 설정값을 외부로 뽑아둔 것이다. 그런데 어디에 있는 외부 설정값을 읽어야 하는지에 따라서
각각 읽는 방법이 다르다는 단점이 있다.
예를 들어서 OS 환경 변수에 두면 System.getenv(key) 를 사용해야 하고, 자바 시스템 속성을 사용하면 System.getProperty(key) 를 사용해야 한다. 만약 OS에 환경 변수를 두었는데, 이후에 정책이 변경되어서 자바
시스템 속성에 환경 변수를 두기로 했다고 가정해보자. 그러면 해당 코드들을 모두 변경해야 한다.
외부 설정값이 어디에 위치하든 상관없이 일관성 있고, 편리하게 key=value 형식의 외부 설정값을 읽을 수 있으면
사용하는 개발자 입장에서 더 편리하고 또 외부 설정값을 설정하는 방법도 더 유연해질 수 있다. 예를 들어서 외부 설정
값을 OS 환경변수를 사용하다가 자바 시스템 속성으로 변경하는 경우에 소스코드를 다시 빌드하지 않고 그대로 사용할 수 있다.
스프링은 이 문제를 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 들에 접근한다.
같은 값이 있을 경우를 대비해서 스프링은 미리 우선순위를 정해두었다. (뒤에서 설명한다.)
설정 데이터(파일)
여기에 우리가 잘 아는 application.properties , application.yml 도 PropertySource 에 추가된다.
따라서 Environment 를 통해서 접근할 수 있다.
커맨드 라인 옵션 인수, 자바 시스템 속성 모두 Environment 를 통해서 동일한 방법으로 읽을 수 있는 것을 확인했다.
스프링은 Environment 를 통해서 외부 설정을 읽는 방법을 추상화했다. 덕분에 자바 시스템 속성을 사용하다가 만약
커맨드 라인 옵션 인수를 사용하도록 읽는 방법이 변경되어도, 개발 소스 코드는 전혀 변경하지 않아도 된다.
우선순위
예를 들어서 커맨드 라인 옵션 인수와 자바 시스템 속성을 다음과 같이 중복해서 설정하면 어떻게 될까?
reacted with thumbs up emoji reacted with thumbs down emoji reacted with laugh emoji reacted with hooray emoji reacted with confused emoji reacted with heart emoji reacted with rocket emoji reacted with eyes emoji
Uh oh!
There was an error while loading. Please reload this page.
-
외부 설정 - OS 환경 변수
조회 방법
실행 결과
설정 방법
OsEnv -src/text 하위
실행 결과

OS 환경 변수를 설정하고, 필요한 곳에서 System.getenv() 를 사용하면 외부 설정을 사용할 수 있다.
이제 데이터베이스 접근 URL과 같은 정보를 OS 환경 변수에 설정해두고 읽어들이면 된다. 예를 들어서 개발 서버에서는 DBURL=dev.db.com 과 같이 설정하고, 운영 서버에서는 DBURL=prod.db.com 와 같이 설정하는 것이다.
이렇게 하면 System.getenv("DBURL") 을 조회할 때 각각 환경에 따라서 서로 다른 값을 읽게 된다.
하지만 OS 환경 변수는 이 프로그램 뿐만 아니라 다른 프로그램에서도 사용할 수 있다. 쉽게 이야기해서 전역 변수 같은 효과가 있다. 여러 프로그램에서 사용하는 것이 맞을 때도 있지만, 해당 애플리케이션을 사용하는 자바 프로그램 안에서만 사용되는 외부 설정값을 사용하고 싶을 때도 있다. 다음에는 특정 자바 프로그램안에서 사용하는 외부 설정을 알아보자.
외부 설정 - 자바 시스템 속성
자바 시스템 속성(Java System properties)은 실행한 JVM 안에서 접근 가능한 외부 설정이다. 추가로 자바가 내부에서 미리 설정해두고 사용하는 속성들도 있다.
자바 시스템 속성은 다음과 같이 자바 프로그램을 실행할 때 사용한다.
JavaSystemProperties - src/test 하위
실행 결과

자바가 기본으로 제공하는 수 많은 속성들이 추가되어 있는 것을 확인할 수 있다. 자바는 내부에서 필요할
때 이런 속성들을 사용하는데, 예를 들어서 file.encoding=UTF-8 를 통해서 기본적인 파일 인코딩 정보 등
으로 사용한다.
이번에는 사용자가 직접 정의하는 자바 시스템 속성을 추가해보자. url, username, password
JavaSystemProperties - 추가
실행 결과

Jar 실행
jar 로 빌드되어 있다면 실행시 다음과 같이 자바 시스템 속성을 추가할 수 있다.
java -Durl=devdb -Dusername=dev_user -Dpassword=dev_pw -jar app.jar
자바 시스템 속성을 자바 코드로 설정하기
참고로 이 방식은 코드 안에서 사용하는 것이기 때문에 외부로 설정을 분리하는 효과는 없다.
외부 설정 - 커맨드 라인 인수
커맨드 라인 인수(Command line arguments)는 애플리케이션 실행 시점에 외부 설정값을 main(args) 메서드의 args 파라미터로 전달하는 방법이다.
다음과 같이 사용한다.
CommandLineV1 -src/test 하위
눌러서 추가할 수 있다.
Jar 실행
key=valu 형식 입력
애플리케이션을 개발할 때는 보통 key=value 형식으로 데이터를 받는 것이 편리하다.
이번에는 커맨드 라인 인수를 다음과 같이 입력하고 실행해보자
url=devdb username=dev_user password=dev_pw실행 결과를 보면 알겠지만 커맨드 라인 인수는 key=value 형식이 아니다. 단순히 문자를 여러게 입력 받는 형식인것이다. 그래서 3가지 문자가 입력되었다.
이것은 파싱되지 않은, 통 문자이다.
이 경우 개발자가 = 을 기준으로 직접 데이터를 파싱해서 key=value 형식에 맞도록 분리해야 한다. 그리고 형식이 배열이기 때문에 루프를 돌면서 원하는 데이터를 찾아야 하는 번거로움도 발생한다.
실제 애플리케이션을 개발할 때는 주로 key=value 형식을 자주 사용하기 때문에 결국 파싱해서 Map 같은 형식으로 변환하도록 직접 개발해야 하는 번거로움이 있다.
외부 설정 - 커맨드 라인 옵션 인수
일반적인 커맨드 라인 인수
커맨드 라인에 전달하는 값은 형식이 없고, 단순히 띄어쓰기로 구분한다.
커맨드 라인 옵션 인수(command line option arguments)
커맨드 라인 인수를 key=value 형식으로 구분하는 방법이 필요하다. 그래서 스프링에서는 커맨드 라인 인수를
key=value 형식으로 편리하게 사용할 수 있도록 스프링 만의 표준 방식을 정의했는데, 그것이 바로 커맨드 라인 옵션 인수이다.
스프링은 커맨드 라인에 - (dash) 2개( -- )를 연결해서 시작하면 key=value 형식으로 정하고 이것을 커맨드 라인 옵션 인수라 한다.
CommandLineV2 - src/test 하위
하면 커맨드 라인 옵션 인수를 규격대로 파싱해서 편리하게 사용할 수 있다.
실행 결과

앞에 사용하지 않았다.
참고
외부 설정 - 커맨드 라인 옵션 인수와 스프링 부트
링 빈으로 등록해둔다. 그리고 그 안에 입력한 커맨드 라인을 저장해둔다. 그래서 해당 빈을 주입 받으면 커맨드 라인으
로 입력한 값을 어디서든 사용할 수 있다.
CommandLineBean - src/main 하위
실행 결과
외부 설정 - 스프링 통합
지금까지 살펴본, 커맨드 라인 옵션 인수, 자바 시스템 속성, OS 환경변수는 모두 외부 설정을 key=value 형식으로
사용할 수 있는 방법이다. 그런데 이 외부 설정값을 읽어서 사용하는 개발자 입장에서 단순하게 생각해보면, 모두
key=value 형식이고, 설정값을 외부로 뽑아둔 것이다. 그런데 어디에 있는 외부 설정값을 읽어야 하는지에 따라서
각각 읽는 방법이 다르다는 단점이 있다.
예를 들어서 OS 환경 변수에 두면 System.getenv(key) 를 사용해야 하고, 자바 시스템 속성을 사용하면 System.getProperty(key) 를 사용해야 한다. 만약 OS에 환경 변수를 두었는데, 이후에 정책이 변경되어서 자바
시스템 속성에 환경 변수를 두기로 했다고 가정해보자. 그러면 해당 코드들을 모두 변경해야 한다.
외부 설정값이 어디에 위치하든 상관없이 일관성 있고, 편리하게 key=value 형식의 외부 설정값을 읽을 수 있으면
사용하는 개발자 입장에서 더 편리하고 또 외부 설정값을 설정하는 방법도 더 유연해질 수 있다. 예를 들어서 외부 설정
값을 OS 환경변수를 사용하다가 자바 시스템 속성으로 변경하는 경우에 소스코드를 다시 빌드하지 않고 그대로 사용할 수 있다.
스프링은 이 문제를 Environment 와 PropertySource 라는 추상화를 통해서 해결한다.
스프링의 외부 설정 통합

PropertySource
Environment
설정 데이터(파일)
여기에 우리가 잘 아는 application.properties , application.yml 도 PropertySource 에 추가된다.
따라서 Environment 를 통해서 접근할 수 있다.
EnvironmentCheck, src/main 하위
정리
커맨드 라인 옵션 인수, 자바 시스템 속성 모두 Environment 를 통해서 동일한 방법으로 읽을 수 있는 것을 확인했다.
스프링은 Environment 를 통해서 외부 설정을 읽는 방법을 추상화했다. 덕분에 자바 시스템 속성을 사용하다가 만약
커맨드 라인 옵션 인수를 사용하도록 읽는 방법이 변경되어도, 개발 소스 코드는 전혀 변경하지 않아도 된다.
우선순위
예를 들어서 커맨드 라인 옵션 인수와 자바 시스템 속성을 다음과 같이 중복해서 설정하면 어떻게 될까?
우선순위는 상식 선에서 딱 2가지만 기억하면 된다.
자바 시스템 속성과 커맨드 라인 옵션 인수의 경우 커맨드 라인 옵션 인수의 범위가 더 좁기 때문에 커맨드 라인 옵션 인수가 우선권을 가진다.
Beta Was this translation helpful? Give feedback.
All reactions