Externalized Configuration :: Spring Boot
Externalized Configuration :: Spring Boot
The RandomValuePropertySource is useful for injecting random values (for example, into secrets or test cases). It can produce integers, longs, uuids, or strings, as shown in the following example: my.secret=${random.value} my.number=${random.int} my.bignum
docs.spring.io
외부 구성
Spring Boot는 다양한 외부 구성 소스를 사용하여 동일한 애플리케이션 코드를 다양한 환경에서 작업할 수 있도록 합니다. 여기에는 Java properties 파일, YAML 파일, 환경 변수 및 명령줄 인수가 포함됩니다.
구성 속성은 @Value 주석을 사용하여 직접 빈에 주입하거나 Spring의 Environment 추상화를 통해 액세스하거나 @ConfigurationProperties를 통해 구조화된 객체에 바인딩할 수 있습니다. Spring Boot는 값의 합리적인 재정의를 허용하도록 설계된 특정 PropertySource 순서를 사용합니다. 나중에 정의된 속성 소스가 이전에 정의된 값을 재정의할 수 있습니다. 소스는 다음 순서로 고려됩니다:
- 기본 속성 (SpringApplication.setDefaultProperties(Map)을 설정하여 지정)
- @Configuration 클래스의 @PropertySource 주석
- 구성 데이터 (예: application.properties 파일)
- RandomValuePropertySource (random.* 속성만 포함)
- OS 환경 변수
- Java 시스템 속성 (System.getProperties())
- java:comp/env의 JNDI 속성
- ServletContext 초기화 매개변수
- ServletConfig 초기화 매개변수
- SPRING_APPLICATION_JSON의 속성 (환경 변수 또는 시스템 속성에 포함된 인라인 JSON)
- 명령줄 인수
- 테스트 속성 (테스트 주석에 사용 가능)
- @DynamicPropertySource 주석이 있는 테스트
- @TestPropertySource 주석이 있는 테스트
- Devtools 글로벌 설정 속성 ($HOME/.config/spring-boot 디렉토리에서 devtools가 활성화된 경우)
구성 데이터 파일은 다음 순서로 고려됩니다:
- jar 내부에 포함된 애플리케이션 속성 (application.properties 및 YAML 변형)
- jar 내부에 포함된 프로필별 애플리케이션 속성 (application-{profile}.properties 및 YAML 변형)
- jar 외부의 애플리케이션 속성 (application.properties 및 YAML 변형)
- jar 외부의 프로필별 애플리케이션 속성 (application-{profile}.properties 및 YAML 변형)
하나의 형식을 사용하는 것이 좋습니다. 동일한 위치에 .properties 및 YAML 형식의 구성 파일이 있는 경우 .properties가 우선합니다. 시스템 속성 대신 환경 변수를 사용하는 경우 대부분의 운영 체제는 점으로 구분된 키 이름을 허용하지 않지만 밑줄을 사용할 수 있습니다 (예: spring.config.name 대신 SPRING_CONFIG_NAME). 환경 변수에서 바인딩하는 방법에 대한 자세한 내용은 환경 변수에서 바인딩하기를 참조하십시오.
애플리케이션이 서블릿 컨테이너 또는 애플리케이션 서버에서 실행되는 경우, 환경 변수 또는 시스템 속성 대신 또는 함께 java:comp/env의 JNDI 속성이나 서블릿 컨텍스트 초기화 매개변수를 사용할 수 있습니다.
구체적인 예를 들어, 다음과 같이 name 속성을 사용하는 @Component를 개발한다고 가정해 보겠습니다:
@Component
public class MyBean {
@Value("${name}")
private String name;
// ...
}
애플리케이션 클래스 경로 (예: jar 내부)에 application.properties 파일이 있어 name에 대한 합리적인 기본 속성 값을 제공합니다. 새로운 환경에서 실행할 때, jar 외부에 제공된 application.properties 파일이 name을 재정의할 수 있습니다. 일회성 테스트를 위해 특정 명령줄 스위치 (예: java -jar app.jar --name="Spring")로 실행할 수 있습니다.
env 및 configprops 엔드포인트는 속성이 특정 값을 가지는 이유를 파악하는 데 유용할 수 있습니다. 이러한 두 엔드포인트를 사용하여 예상치 못한 속성 값을 진단할 수 있습니다. 자세한 내용은 여기에서 확인할 수 있습니다.
이제 더 궁금한 점이 있으신가요? 😊
알겠습니다. 페이지의 전체 내용을 번역해드리겠습니다:
외부 구성
Spring Boot는 다양한 외부 구성 소스를 사용하여 동일한 애플리케이션 코드를 다양한 환경에서 작업할 수 있도록 합니다. 여기에는 Java properties 파일, YAML 파일, 환경 변수 및 명령줄 인수가 포함됩니다.
구성 속성은 @Value 주석을 사용하여 직접 빈에 주입하거나 Spring의 Environment 추상화를 통해 액세스하거나 @ConfigurationProperties를 통해 구조화된 객체에 바인딩할 수 있습니다. Spring Boot는 값의 합리적인 재정의를 허용하도록 설계된 특정 PropertySource 순서를 사용합니다. 나중에 정의된 속성 소스가 이전에 정의된 값을 재정의할 수 있습니다. 소스는 다음 순서로 고려됩니다:
- 기본 속성 (SpringApplication.setDefaultProperties(Map)을 설정하여 지정)
- @Configuration 클래스의 @PropertySource 주석
- 구성 데이터 (예: application.properties 파일)
- RandomValuePropertySource (random.* 속성만 포함)
- OS 환경 변수
- Java 시스템 속성 (System.getProperties())
- java:comp/env의 JNDI 속성
- ServletContext 초기화 매개변수
- ServletConfig 초기화 매개변수
- SPRING_APPLICATION_JSON의 속성 (환경 변수 또는 시스템 속성에 포함된 인라인 JSON)
- 명령줄 인수
- 테스트 속성 (테스트 주석에 사용 가능)
- @DynamicPropertySource 주석이 있는 테스트
- @TestPropertySource 주석이 있는 테스트
- Devtools 글로벌 설정 속성 ($HOME/.config/spring-boot 디렉토리에서 devtools가 활성화된 경우)
구성 데이터 파일은 다음 순서로 고려됩니다:
- jar 내부에 포함된 애플리케이션 속성 (application.properties 및 YAML 변형)
- jar 내부에 포함된 프로필별 애플리케이션 속성 (application-{profile}.properties 및 YAML 변형)
- jar 외부의 애플리케이션 속성 (application.properties 및 YAML 변형)
- jar 외부의 프로필별 애플리케이션 속성 (application-{profile}.properties 및 YAML 변형)
하나의 형식을 사용하는 것이 좋습니다. 동일한 위치에 .properties 및 YAML 형식의 구성 파일이 있는 경우 .properties가 우선합니다. 시스템 속성 대신 환경 변수를 사용하는 경우 대부분의 운영 체제는 점으로 구분된 키 이름을 허용하지 않지만 밑줄을 사용할 수 있습니다 (예: spring.config.name 대신 SPRING_CONFIG_NAME). 환경 변수에서 바인딩하는 방법에 대한 자세한 내용은 환경 변수에서 바인딩하기를 참조하십시오.
애플리케이션이 서블릿 컨테이너 또는 애플리케이션 서버에서 실행되는 경우, 환경 변수 또는 시스템 속성 대신 또는 함께 java:comp/env의 JNDI 속성이나 서블릿 컨텍스트 초기화 매개변수를 사용할 수 있습니다.
구체적인 예를 들어, 다음과 같이 name 속성을 사용하는 @Component를 개발한다고 가정해 보겠습니다:
@Component
public class MyBean {
@Value("${name}")
private String name;
// ...
}
애플리케이션 클래스 경로 (예: jar 내부)에 application.properties 파일이 있어 name에 대한 합리적인 기본 속성 값을 제공합니다. 새로운 환경에서 실행할 때, jar 외부에 제공된 application.properties 파일이 name을 재정의할 수 있습니다. 일회성 테스트를 위해 특정 명령줄 스위치 (예: java -jar app.jar --name="Spring")로 실행할 수 있습니다.
env 및 configprops 엔드포인트는 속성이 특정 값을 가지는 이유를 파악하는 데 유용할 수 있습니다. 이러한 두 엔드포인트를 사용하여 예상치 못한 속성 값을 진단할 수 있습니다.
명령줄 속성 접근
기본적으로, SpringApplication은 모든 명령줄 옵션 인수(즉, --server.port=9000과 같은 --로 시작하는 인수)를 속성으로 변환하고 이를 Spring Environment에 추가합니다. 앞서 언급했듯이, 명령줄 속성은 항상 파일 기반 속성 소스보다 우선합니다.
명령줄 속성이 Environment에 추가되지 않도록 하려면, SpringApplication.setAddCommandLineProperties(false)를 사용하여 이를 비활성화할 수 있습니다.
JSON 애플리케이션 속성
환경 변수와 시스템 속성은 일부 속성 이름을 사용할 수 없도록 제한하는 경우가 많습니다. 이를 해결하기 위해 Spring Boot는 단일 JSON 구조로 속성 블록을 인코딩할 수 있도록 허용합니다. 애플리케이션이 시작될 때, 모든 spring.application.json 또는 SPRING_APPLICATION_JSON 속성이 구문 분석되어 Environment에 추가됩니다. 예를 들어, SPRING_APPLICATION_JSON 속성은 UN*X 셸에서 환경 변수로 제공될 수 있습니다:
$ SPRING_APPLICATION_JSON='{"my":{"name":"test"}}' java -jar myapp.jar
위 예제에서는 Spring Environment에 my.name=test 속성이 추가됩니다. 동일한 JSON은 시스템 속성으로도 제공될 수 있습니다:
$ java -Dspring.application.json='{"my":{"name":"test"}}' -jar myapp.jar
또는 명령줄 인수로 JSON을 제공할 수도 있습니다:
$ java -jar myapp.jar --spring.application.json='{"my":{"name":"test"}}'
클래식 애플리케이션 서버에 배포하는 경우, java:comp/env/spring.application.json이라는 JNDI 변수를 사용할 수도 있습니다. JSON의 null 값은 결과 속성 소스에 추가되지만, PropertySourcesPropertyResolver는 null 속성을 누락된 값으로 처리합니다. 이는 JSON이 null 값으로 하위 순서 속성 소스의 속성을 재정의할 수 없음을 의미합니다.
이제 페이지의 다른 부분도 번역해드릴까요? 😊
알겠습니다. 페이지의 나머지 부분을 번역해드리겠습니다:
외부 애플리케이션 속성
Spring Boot는 애플리케이션이 시작될 때 다음 위치에서 application.properties 및 application.yaml 파일을 자동으로 찾고 로드합니다:
- 클래스 경로에서
- 클래스 경로 루트
- 클래스 경로 /config 패키지
- 현재 디렉토리에서
- 현재 디렉토리
- 현재 디렉토리의 config/ 하위 디렉토리
- config/ 하위 디렉토리의 즉시 하위 디렉토리
목록은 우선 순위에 따라 정렬됩니다 (하위 항목의 값이 이전 항목을 재정의합니다). 로드된 파일의 문서는 Spring Environment에 PropertySource 인스턴스로 추가됩니다. 구성 파일 이름으로 application을 사용하지 않으려면 spring.config.name 환경 속성을 지정하여 다른 파일 이름으로 전환할 수 있습니다. 예를 들어, myproject.properties 및 myproject.yaml 파일을 찾으려면 다음과 같이 애플리케이션을 실행할 수 있습니다:
$ java -jar myproject.jar --spring.config.name=myproject
명시적인 위치를 참조하려면 spring.config.location 환경 속성을 사용하여 지정할 수 있습니다. 이 속성은 쉼표로 구분된 하나 이상의 위치 목록을 허용합니다. 다음 예제는 두 개의 별도 파일을 지정하는 방법을 보여줍니다:
$ java -jar myproject.jar --spring.config.location=\\ optional:classpath:/default.properties,\\ optional:classpath:/override.properties
위치가 선택 사항이고 존재하지 않아도 괜찮다면 optional: 접두사를 사용하십시오. spring.config.name, spring.config.location 및 spring.config.additional-location은 로드할 파일을 결정하기 위해 매우 일찍 사용됩니다. 이들은 환경 속성 (일반적으로 OS 환경 변수, 시스템 속성 또는 명령줄 인수)으로 정의되어야 합니다. spring.config.location에 디렉토리 (파일이 아닌)가 포함된 경우, /로 끝나야 합니다. 런타임에 spring.config.name에서 생성된 이름이 추가되어 로드됩니다. spring.config.location에 지정된 파일은 직접 가져옵니다. 디렉토리 및 파일 위치 값은 프로필별 파일을 확인하기 위해 확장됩니다. 예를 들어, spring.config.location이 classpath:myconfig.properties인 경우, classpath:myconfig-<profile>.properties 파일도 로드됩니다.
대부분의 상황에서, 추가하는 각 spring.config.location 항목은 단일 파일 또는 디렉토리를 참조합니다. 위치는 정의된 순서대로 처리되며, 나중에 정의된 항목이 이전 항목의 값을 재정의할 수 있습니다. 복잡한 위치 설정이 있고 프로필별 구성 파일을 사용하는 경우, Spring Boot가 이를 그룹화하는 방법을 알 수 있도록 추가 힌트를 제공해야 할 수 있습니다. 위치 그룹은 동일한 수준으로 간주되는 위치 모음입니다. 예를 들어, 모든 클래스 경로 위치를 그룹화한 다음 모든 외부 위치를 그룹화할 수 있습니다. 위치 그룹 내의 항목은 ;로 구분해야 합니다. 자세한 내용은 프로필별 파일 섹션의 예제를 참조하십시오.
spring.config.location을 사용하여 구성된 위치는 기본 위치를 대체합니다. 예를 들어, spring.config.location이 optional:classpath:/custom-config/,optional:file:./custom-config/ 값으로 구성된 경우, 고려되는 전체 위치 집합은 다음과 같습니다:
- optional:classpath:custom-config/
- optional:file:./custom-config/
추가 위치를 대체하는 대신 추가하려면 spring.config.additional-location을 사용할 수 있습니다. 추가 위치에서 로드된 속성은 기본 위치의 속성을 재정의할 수 있습니다. 예를 들어, spring.config.additional-location이 optional:classpath:/custom-config/,optional:file:./custom-config/ 값으로 구성된 경우, 고려되는 전체 위치 집합은 다음과 같습니다:
- optional:classpath:/;optional:classpath:/config/
- optional:file:./;optional:file:./config/;optional:file:./config/*/
- optional:classpath:custom-config/
- optional:file:./custom-config/
이 검색 순서는 하나의 구성 파일에 기본 값을 지정한 다음 다른 파일에서 선택적으로 해당 값을 재정의할 수 있도록 합니다. 기본 위치 중 하나에 application.properties (또는 spring.config.name으로 선택한 다른 기본 이름)에서 애플리케이션의 기본 값을 제공할 수 있습니다. 이러한 기본 값은 런타임에 사용자 지정 위치 중 하나에 있는 다른 파일로 재정의할 수 있습니다.
선택적 위치
기본적으로, 지정된 구성 데이터 위치가 존재하지 않으면 Spring Boot는 ConfigDataLocationNotFoundException을 발생시키고 애플리케이션이 시작되지 않습니다. 위치를 지정하고 싶지만 항상 존재하지 않아도 괜찮다면 optional: 접두사를 사용할 수 있습니다. 이 접두사는 spring.config.location 및 spring.config.additional-location 속성뿐만 아니라 spring.config.import 선언에서도 사용할 수 있습니다. 예를 들어, spring.config.import 값이 optional:file:./myconfig.properties인 경우, myconfig.properties 파일이 없어도 애플리케이션이 시작됩니다. 모든 ConfigDataLocationNotFoundException 오류를 무시하고 항상 애플리케이션을 시작하려면 spring.config.on-not-found 속성을 사용할 수 있습니다. SpringApplication.setDefaultProperties(…)를 사용하거나 시스템/환경 변수로 값을 설정하십시오.
와일드카드 위치
구성 파일 위치에 마지막 경로 세그먼트로 * 문자가 포함된 경우, 이는 와일드카드 위치로 간주됩니다. 와일드카드는 구성이 로드될 때 확장되어 즉시 하위 디렉토리도 확인됩니다. 와일드카드 위치는 Kubernetes와 같은 환경에서 여러 구성 속성 소스가 있는 경우 특히 유용합니다. 예를 들어, Redis 구성과 MySQL 구성이 있는 경우, 두 개의 구성 파일을 별도로 유지하면서도 application.properties 파일에 모두 포함되도록 할 수 있습니다. 이 경우, config// 와일드카드 위치를 사용하면 두 파일이 모두 처리됩니다. 기본적으로 Spring Boot는 기본 검색 위치에 config//를 포함합니다. 이는 jar 외부의 /config 디렉토리의 모든 하위 디렉토리가 검색됨을 의미합니다. spring.config.location 및 spring.config.additional-location 속성을 사용하여 와일드카드 위치를 직접 사용할 수 있습니다. 와일드카드 위치는 하나의 *만 포함해야 하며, 디렉토리 검색 위치의 경우 */로 끝나야 하고, 파일 검색 위치의 경우 */<filename>으로 끝나야 합니다. 와일드카드가 포함된 위치는 파일 이름의 절대 경로를 기준으로 알파벳순으로 정렬됩니다. 와일드카드 위치는 외부 디렉토리에서만 작동합니다. 클래스 경로 위치에서는 와일드카드를 사용할 수 없습니다.
프로필별 파일
Spring Boot는 application 속성 파일뿐만 아니라 프로필별 파일도 로드하려고 시도합니다. 프로필별 파일은 application-{profile} 명명 규칙을 사용합니다. 예를 들어, 애플리케이션이 prod라는 프로필을 활성화하고 YAML 파일을 사용하는 경우, application.yaml 및 application-prod.yaml이 고려됩니다. 프로필별 속성은 표준 application.properties와 동일한 위치에서 로드되며, 프로필별 파일은 항상 비프로필 파일을 재정의합니다. 여러 프로필이 지정된 경우, 마지막으로 지정된 프로필이 우선합니다. 예를 들어, spring.profiles.active 속성에 prod,live 프로필이 지정된 경우, application-prod.properties의 값은 application-live.properties의 값으로 재정의될 수 있습니다. 마지막으로 지정된 프로필이 우선하는 전략은 위치 그룹 수준에서 적용됩니다. spring.config.location이 classpath:/cfg/,classpath:/ext/인 경우, /cfg/ 및 /ext/ 파일이 동일한 수준에서 처리되지 않습니다. 예를 들어, prod,live 예제를 계속 사용하면 다음 파일이 있을 수 있습니다:
- /cfg/application-live.properties
- /ext/application-live.properties
- /ext/application-prod.properties
spring.config.location이 classpath:/cfg/,classpath:/ext/인 경우, 모든 /cfg 파일이 모든 /ext 파일보다 먼저 처리됩니다:
- /cfg/application-live.properties
- /ext/application-prod.properties
- /ext/application-live.properties
대신 classpath:/cfg/;classpath:/ext/ (세미콜론 구분 기호 사용)인 경우, /cfg 및 /ext가 동일한 수준에서 처리됩니다:
- /ext/application-prod.properties
- /cfg/application-live.properties
- /ext/application-live.properties
Environment에는 기본 프로필 집합 (기본적으로 [default])이 있으며, 활성 프로필이 설정되지 않은 경우 사용됩니다. 즉, 명시적으로 프로필이 활성화되지 않은 경우, application-default의 속성이 고려됩니다. 속성 파일은 한 번만 로드됩니다. 프로필별 속성 파일을 직접 가져온 경우, 두 번째로 가져오지 않습니다.
추가 데이터 가져오기
애플리케이션 속성은 spring.config.import 속성을 사용하여 다른 위치에서 추가 구성 데이터를 가져올 수 있습니다. 가져오기는 발견되는 즉시 처리되며, 가져오기를 선언한 문서 바로 아래에 추가 문서로 삽입됩니다. 예를 들어, 클래스 경로 application.properties 파일에 다음과 같은 내용이 포함될 수 있습니다:
spring.config.import=optional:classpath:additional.properties
위 예제에서는 additional.properties 파일이 발견되면 즉시 로드되고, application.properties 파일의 속성을 재정의할 수 있습니다. 가져오기는 ConfigDataLocationNotFoundException을 발생시키지 않도록 optional: 접두사를 사용할 수 있습니다. 가져오기는 spring.config.import 속성뿐만 아니라 spring.config.location 및 spring.config.additional-location 속성에서도 사용할 수 있습니다.
프로필별 가져오기
프로필별 가져오기는 spring.config.import 속성에서 선언된 위치에 대해 자동으로 처리됩니다. 예를 들어, 다음과 같은 application.properties 파일이 있다고 가정해 보겠습니다:
spring.config.import=optional:classpath:additional.properties
prod 프로필이 활성화된 경우, Spring Boot는 다음 위치를 확인합니다:
- classpath:additional-prod.properties
- classpath:additional.properties
프로필별 가져오기는 기본 위치와 동일한 방식으로 처리됩니다. 즉, 마지막으로 지정된 프로필이 우선합니다. 예를 들어, spring.profiles.active 속성에 prod,live 프로필이 지정된 경우, additional-prod.properties의 값은 additional-live.properties의 값으로 재정의될 수 있습니다.
암호화된 데이터 가져오기
Spring Boot는 암호화된 구성 데이터를 가져올 수 있는 기능을 제공합니다. 이를 위해 spring.config.import 속성에 암호화된 위치를 지정할 수 있습니다. 예를 들어, 다음과 같은 application.properties 파일이 있다고 가정해 보겠습니다:
spring.config.import=optional:encrypted:classpath:encrypted.properties
위 예제에서는 encrypted.properties 파일이 암호화된 데이터로 로드됩니다. 암호화된 데이터는 Spring Boot의 ConfigDataLocationResolver 인터페이스를 구현하여 처리할 수 있습니다.
환경 변수에서 바인딩하기
Spring Boot는 환경 변수에서 속성을 바인딩할 수 있는 기능을 제공합니다. 이를 위해 spring.config.import 속성에 환경 변수를 지정할 수 있습니다. 예를 들어, 다음과 같은 application.properties 파일이 있다고 가정해 보겠습니다:
spring.config.import=optional:env:MY_ENV_VAR
위 예제에서는 MY_ENV_VAR 환경 변수가 속성으로 로드됩니다. 환경 변수는 Spring Boot의 ConfigDataLocationResolver 인터페이스를 구현하여 처리할 수 있습니다.
명령줄 인수에서 바인딩하기
Spring Boot는 명령줄 인수에서 속성을 바인딩할 수 있는 기능을 제공합니다. 이를 위해 spring.config.import 속성에 명령줄 인수를 지정할 수 있습니다. 예를 들어, 다음과 같은 application.properties 파일이 있다고 가정해 보겠습니다:
spring.config.import=optional:cmd:--my.arg=value
위 예제에서는 --my.arg=value 명령줄 인수가 속성으로 로드됩니다. 명령줄 인수는 Spring Boot의 ConfigDataLocationResolver 인터페이스를 구현하여 처리할 수 있습니다.