섹션 6 : 외부 설정과 프로필 1

최용석·2024년 1월 5일
post-thumbnail

외부 설정이란?

하나의 애플리케이션을 여러 다른 환경에서 사용해야 할 때가 있다. 문제는 환경마다 설정 값이 따로 존재하는데, 이때 애플리케이션을 실행할 때 필요한 여러 설정 값들을 어플리케이션 외부 또는 내부에 정의할 수 있는 기능을 말한다.

외부 설정 4가지 방법

  1. OS 환경 변수 - OS에서 지원하는 외부 설정, 해당 OS를 사용하는 모든 프로세스에서 사용
  2. 자바 시스템 속성 - 자바에서 지원하는 외부 설정, 해당 JVM안에서 사용
  3. 자바 커맨드 라인 인수 - 커맨드 라인에서 전달하는 외부 설정, 실행시 main(args) 메서드에서 사용
  4. 외부 파일(설정 데이터): 프로그램에서 외부 파일을 직접 읽어서 사용
    • 애플리케이션에서 특정 위치의 파일을 읽도록 해둔다. 예) data/hello.txt
    • 그리고 각 서버마다 해당 파일안에 다른 설정 정보를 남겨둔다.
      - 개발 서버 hello.txt : url=dev.db.com
      • 운영 서버 hello.txt : url=prod.db.com

외부 설정 - OS 환경 변수

OS 환경 변수(OS environment variables)는 해당 OS를 사용하는 모든 프로그램에서 읽을 수 있는 설정값이다. 한마디로 다른 외부 설정과 비교해서 사용 범위가 가장 넓다.

외부 설정 - 자바 시스템 속성

자바 시스템 속성(Java System properties)은 실행한 JVM 안에서 접근 가능한 외부 설정이다. 추가로 자바가 내부에서 미리 설정해두고 사용하는 속성들도 있다.

  • Jar 실행
    • java -Durl=dev -jar app.jar
  • IDE에서 실행시 VM 옵션 추가
    • -D VM 옵션을 통해서 key=value 형식을 주면 된다.

외부 설정 - 커맨드 라인 인수

커맨드 라인 인수(Command line arguments)는 애플리케이션 실행 시점에 외부 설정값을 main(args) 메서드의 args 파라미터로 전달하는 방법이다.

  • Jar 실행
    • 예) java -jar app.jar dataA dataB
    • 필요한 데이터를 마지막 위치에 스페이스로 구분해서 전달하면 된다. 이 경우 dataA , dataB 2개의 문자가 args 에 전달된다.
  • IDE에서 실행시 커맨드 라인 인수 추가
    • dataA dataB
    • 커맨드 라인 인수는 공백(space)으로 구분한다.

하지만 커맨드 라인 인수는 파싱되지 않은 통 문자 형식으로 key=value 형식으로 사용하기 위해선 스프링에서 정의한 커맨드 라인 옵션 인수를 사용한다.

커맨드 라인 옵션 인수

일반적인 커맨드 라인 인수

  • aaa bbb -> [aaa, bbb] 값 2개
  • hello world -> [hello, world] 값 2개
  • "hello world" -> [hello world] (공백을 연결하려면 "를 사용하면 된다.) 값 1개
  • key=value -> [key=value] 값 1개

스프링에서는 커맨드 라인 인수를 key=value 형식으로 편리하게 사용할 수 있도록 스프링 만의 표준 방식을 정의했는데, 그것이 바로 커맨드 라인 옵션 인수이다.

  • --key=value 형식으로 사용한다.
  • --username=userA --username=userB 하나의 키에 여러 값도 지정할 수 있다.

외부 설정 - 스프링 통합

커맨드 라인 옵션 인수, 자바 시스템 속성, OS 환경변수는 모두 외부 설정을 key=value 형식으로 사용할 수 있다. 하지만 어디에 있는 외부 설정값을 읽어야 하는지에 따라서 각각 읽는 방법이 다르다는 단점이 있다. 스프링은 이 문제를 Environment 와 PropertySource 라는 추상화를 통해서 해결한다

스프링의 외부 설정 통합

PropertySource

  • org.springframework.core.env.PropertySource
  • 스프링은 PropertySource 라는 추상 클래스를 제공하고, 각각의 외부 설정를 조회하는 XxxPropertySource 구현체를 만들어두었다.
  • 스프링은 로딩 시점에 필요한 PropertySource 들을 생성하고, Environment 에서 사용할 수 있게 연결해둔다.

Environment

  • org.springframework.core.env.Environment
  • Environment 를 통해서 특정 외부 설정에 종속되지 않고, 일관성 있게 key=value 형식의 외부 설정에 접근할 수 있다.
    • environment.getProperty(key) 를 통해서 값을 조회할 수 있다.
    • Environment 는 내부에서 여러 과정을 거쳐서 PropertySource 들에 접근한다.
    • 같은 값이 있을 경우를 대비해서 스프링은 미리 우선순위를 정해두었다.
  • 모든 외부 설정은 이제 Environment 를 통해서 조회하면 된다.

우선순위

우선순위는 위에서 아래로 적용된다. 아래가 더 우선순위가 높다.

자주 사용하는 우선순위

  • 설정 데이터( application.properties )
  • OS 환경변수
  • 자바 시스템 속성
  • 커맨드 라인 옵션 인수
  • @TestPropertySource (테스트에서 사용)

설정 데이터 우선순위

  • jar 내부 application.properties
  • jar 내부 프로필 적용 파일 application-{profile}.properties
  • jar 외부 application.properties
  • jar 외부 프로필 적용 파일 application-{profile}.properties

우선순위 이해 방법

  • 더 유연한 것이 우선권을 가진다. (변경하기 어려운 파일 보다 실행시 원하는 값을 줄 수 있는 자바 시스템 속성이 더 우선권을 가진다.)
  • 범위가 넒은 것 보다 좁은 것이 우선권을 가진다.
    • OS 환경변수 보다 자바 시스템 속성이 우선권이 있다.
    • 자바 시스템 속성 보다 커맨드 라인 옵션 인수가 우선권이 있다.
profile
호기심이 많은 백엔드 개발자

0개의 댓글