IT/SpringBoot

스프링 부트 #4.2 외부화된 구성

blogood 2020. 6. 14. 19:58
반응형

4.2. 외부화된 구성

Spring Boot를 사용하면 다양한 환경에서 동일한 응용 프로그램 코드로 작업할 수 있도록 구성을 외부화할 수 있습니다. 속성 파일, YAML 파일, 환경 변수 및 명령줄 인수를 사용하여 구성을 외부화할 수 있습니다. 속성 값은 어노기를 사용하여 콩에 직접 주입하거나 스프링의 추상화를 통해 액세스하거나 구조화 된 개체에 바인딩할 수 있습니다.@ValueEnvironment@ConfigurationProperties

Spring Boot는 값을 현명하게 재정의할 수 있도록 설계된 매우 특별한 순서를 사용합니다. 속성은 다음 순서로 간주됩니다.PropertySource

  1. devtools가 활성화될 때 디렉터리에서 글로벌 설정 속성을 개발합니다.$HOME/.config/spring-boot
  2. 테스트에 @TestPropertySource 주석을 입력합니다.
  3. properties 테스트의 속성입니다. 응용 프로그램의 특정 조각을 테스트하기 위한 @SpringBootTest 및 테스트 주석에서 사용할 수 있습니다.
  4. 명령줄 인수입니다.
  5. 속성(환경 변수 또는 시스템 속성에 포함된 인라인 JSON).SPRING_APPLICATION_JSON
  6. ServletConfig 매개 변수를 시중합니다.
  7. ServletContext 매개 변수를 시중합니다.
  8. JNDI에서 속성 .java:comp/env
  9. 자바 시스템 속성().System.getProperties()
  10. OS 환경 변수입니다.
  11. 에만 속성이 있는 A .RandomValuePropertySourcerandom.*
  12. 패키지된 jar(및 YAML 변형) 외부의 프로필 별 응용 프로그램 속성입니다.application-{profile}.properties
  13. jar 내부에 패키지된 프로필별 응용 프로그램 속성(및 YAML 변형).application-{profile}.properties
  14. 패키지 된 항아리 (및 YAML 변형) 외부 응용 프로그램 속성.application.properties
  15. jar 내부에 패키지된 응용 프로그램 속성(및 YAML 변형).application.properties
  16. 수업에 @PropertySource 주석을 입력합니다. 응용 프로그램 컨텍스트가 새로 고칠 때까지 이러한 속성 원본이 추가되지 않습니다. 새로 고침이 시작되기 전에 읽는 특정 속성을 구성하기에는 너무 늦었습니다.@ConfigurationEnvironmentlogging.*spring.main.*
  17. 기본 속성(설정별로 지정).SpringApplication.setDefaultProperties

구체적인 예제를 제공하려면 다음 예제와 같이 속성을 사용하는 속성을 개발한다고 가정합니다.@Componentname

import org.springframework.stereotype.*;
import org.springframework.beans.factory.annotation.*;

@Component
public class MyBean {

    @Value("${name}")
    private String name;

    // ...

}

응용 프로그램 클래스경로(예: jar 내부)에서 .에 대한 합리적인 기본 속성 값을 제공하는 파일을 가질 수 있습니다. 새 환경에서 실행하는 경우. 일회성 테스트의 경우 특정 명령줄 스위치(예:)로 시작할 수 있습니다.application.propertiesnameapplication.propertiesnamejava -jar app.jar --name="Spring"

스프링 부트은 구성 파일을 로드할 때 와일드카드 위치를 지원합니다. 기본적으로 항아리 외부의 와일드카드 위치가 지원됩니다. 와일드카드 위치는 지정할 때 지원되며.config/*/spring.config.additional-locationspring.config.location

와일드카드 위치는 여러 개의 구성 속성소스가 있는 경우 Kubernetes와 같은 환경에서 특히 유용합니다. 예를 들어 Redis 구성과 일부 MySQL 구성이 있는 경우 두 구성을 별도로 유지해야 하는 반면 앱에서 바인딩할 수 있는 두 구성이 모두 있어야 할 수 있습니다. 이로 인해 두 개의 개별 파일이 와 같은 다른 위치에 장착될 수 있습니다. 이 경우 와일드카드 위치를 갖는 경우 두 파일이 모두 처리됩니다.application.propertiesapplication.properties/config/redis/application.properties/config/mysql/application.propertiesconfig/*/

  와일드카드 위치에는 디렉터리 또는 파일인 검색 위치에 대해 하나만 포함해야 합니다. 와일드카드가 있는 위치는 파일 이름의 절대 경로를 기반으로 알파벳순으로 정렬됩니다. /*/<filename>
 

속성은 환경 변수가 있는 명령줄에 제공될 수 있습니다. 예를 들어 UN*X 셸에서 다음 줄을 사용할 수 있습니다.SPRING_APPLICATION_JSON

$ SPRING_APPLICATION_JSON='{"acme":{"name":"test"}}' java -jar myapp.jar

앞의 예제에서는 스프링에서 끝납니다. 다음 예제와 같이 시스템 속성과 마찬가지로 JSON을 제공할 수도 있습니다.acme.name=testEnvironmentspring.application.json

$ java -Dspring.application.json='{"name":"test"}' -jar myapp.jar

다음 예제와 같이 명령줄 인수를 사용하여 JSON을 제공할 수도 있습니다.

$ java -jar myapp.jar --spring.application.json='{"name":"test"}'

JSON을 JNDI 변수로 제공할 수도 있습니다.java:comp/env/spring.application.json

4.2.1. 임의값 구성

이 값은 임의값(예: 비밀 또는 테스트 사례)을 삽입하는 데 유용합니다. 다음 예제와 같이 정수, 롱, uuid 또는 문자열을 생성할 수 있습니다.RandomValuePropertySource

my.secret=${random.value}
my.number=${random.int}
my.bignumber=${random.long}
my.uuid=${random.uuid}
my.number.less.than.ten=${random.int(10)}
my.number.in.range=${random.int[1024,65536]}

구문은 모든 문자와 정수입니다. 제공되면 최소 값이며 최대 값(독점)입니다.random.int*OPEN value (,max) CLOSEOPEN,CLOSEvalue,maxmaxvaluemax

4.2.2. 명령줄 속성에 액세스

기본적으로 명령줄 옵션 인수(즉, 인수(예: 인수)를 a로 변환하고 스프링에 추가합니다. 앞에서 설명한 것처럼 명령줄 속성은 항상 다른 속성 원본보다 우선합니다.SpringApplication----server.port=9000propertyEnvironment

명령줄 속성을 추가하지 않으려면 를 사용하여 비활성화할 수 있습니다.EnvironmentSpringApplication.setAddCommandLineProperties(false)

4.2.3. 응용 프로그램 속성 파일

SpringApplication 다음 위치의 파일에서 속성을 로드하고 스프링에 추가합니다.application.propertiesEnvironment

  1. 현재 디렉터리 의 하위 디렉터리/config
  2. 현재 디렉터리
  3. 클래스패스 패키지/config
  4. 클래스 경로 루트

목록은 우선 순위에 따라 정렬됩니다(목록에서 더 높은 위치에 정의된 속성은 하위 위치에 정의된 속성을 재정의합니다).

  YAML('.yml') 파일을 '.properties'의 대안으로 사용할 수도 있습니다.

구성 파일 이름으로 좋아하지 않는 경우 환경 속성을 지정하여 다른 파일 이름으로 전환할 수 있습니다. 환경 속성(디렉토리 위치 또는 파일 경로의 쉼표 구분 목록)을 사용하여 명시적 위치를 참조할 수도 있습니다. 다음 예제에서는 다른 파일 이름을 지정하는 방법을 보여 주습니다.application.propertiesspring.config.namespring.config.location

$ java -jar myproject.jar --spring.config.name=myproject

다음 예제에서는 두 위치를 지정하는 방법을 보여 주습니다.

$ java -jar myproject.jar --spring.config.location=classpath:/default.properties,classpath:/override.properties
  spring.config.name 로드해야 하는 파일을 결정하기 위해 매우 일찍 사용됩니다. 환경 속성(일반적으로 OS 환경 변수, 시스템 속성 또는 명령줄 인수)으로 정의되어야 합니다. spring.config.location

디렉터리(파일이 아닌)가 포함된 경우 종료해야 하며 런타임에 프로필별 파일 이름을 포함하여 로드되기 전에 생성된 이름으로 추가해야 합니다. 에 지정된 파일은 프로필 별 변형을 지원하지 않고 있는 대로 사용되며 프로필별 속성에 의해 재정의됩니다.spring.config.location/spring.config.namespring.config.location

컨피그 위치는 역순으로 검색됩니다. 기본적으로 구성된 위치는. 결과 검색 순서는 다음과 같은 것입니다.classpath:/,classpath:/config/,file:./,file:./config/*/,file:./config/

  1. file:./config/
  2. file:./config/*/
  3. file:./
  4. classpath:/config/
  5. classpath:/

사용자 지정 구성 위치는 사용하여 구성되면 기본 위치를 대체합니다. 예를 들어 값으로 구성된 경우 검색 순서는 다음과 같은 것입니다.spring.config.locationspring.config.locationclasspath:/custom-config/,file:./custom-config/

  1. file:./custom-config/
  2. classpath:custom-config/

또는 사용자 지정 구성 위치는 사용하여 구성될 때 기본 위치 외에 사용됩니다. 기본 위치 전에 추가 위치를 검색합니다. 예를 들어 추가 위치가 구성되면 검색 순서는 다음과 같습니다.spring.config.additional-locationclasspath:/custom-config/,file:./custom-config/

  1. file:./custom-config/
  2. classpath:custom-config/
  3. file:./config/
  4. file:./config/*/
  5. file:./
  6. classpath:/config/
  7. classpath:/

이 검색 순서를 사용하면 한 구성 파일에 기본 값을 지정한 다음 다른 구성에서 해당 값을 선택적으로 재정의할 수 있습니다. 기본 위치 중 하나에서 응용 프로그램에 대한 기본 값(또는 선택한 다른 기본 이름)을 제공할 수 있습니다. 그런 다음 이러한 기본 값은 런타임에 사용자 지정 위치 중 하나에 있는 다른 파일로 재정의할 수 있습니다.application.propertiesspring.config.name

  시스템 속성이 아닌 환경 변수를 사용하는 경우 대부분의 운영 체제는 기간 구분된 키 이름을 허용하지 않지만 대신 밑줄(예: 대신)을 사용할 수 있습니다. 자세한 내용은 환경 변수의 바인딩을 참조하십시오. SPRING_CONFIG_NAMEspring.config.name
  응용 프로그램이 컨테이너에서 실행되는 경우 JNDI 속성(in) 또는 서슬레 컨텍스트 초기화 매개 변수대신 또는 환경 변수 또는 시스템 속성을 사용할 수 있습니다. java:comp/env

4.2.4. 프로필별 속성

파일 외에도 다음 명명 규칙을 사용하여 프로필별 속성을 정의할 수도 있습니다. 활성 프로파일이 설정되지 않으면 사용되는 기본 프로파일 집합(기본적으로)이 있습니다. 즉, 프로파일이 명시적으로 활성화되지 않으면 속성이 로드됩니다.application.propertiesapplication-{profile}.propertiesEnvironment[default]application-default.properties

프로필별 속성은 프로필 별 파일이 패키지된 항아리 내부 또는 외부에 있는지 여부에 관계없이 프로필 별 파일이 항상 비특정 파일을 우선하는 표준과 동일한 위치에서 로드됩니다.application.properties

여러 프로파일을 지정하면 마지막 승리 전략이 적용됩니다. 예를 들어 속성에서 지정한 프로필은 API를 통해 구성된 프로파일이후에 추가되므로 우선합니다.spring.profiles.activeSpringApplication

  파일을 지정한 경우 해당 파일의 프로필 별 변형은 고려되지 않습니다. 프로필별 속성을 사용하려는 경우 디렉터리를 사용합니다. spring.config.locationspring.config.location

4.2.5. 속성의 자리 표시자

이 값은 사용 시 기존값을 통해 필터링되므로 이전에 정의된 값(예: 시스템 속성)을 참조할 수 있습니다.application.propertiesEnvironment

app.name=MyApp
app.description=${app.name} is a Spring Boot application
  이 기술을 사용하여 기존 스프링 부트 속성의 "짧은" 변형을 만들 수도 있습니다. 자세한 내용은 '짧은' 명령줄 인수 사용 방법을 참조하십시오.

4.2.6. 속성 암호화

스프링 부트은 속성 값 암호화에 대한 기본 지원도 제공하지 않지만 스프링에 포함된 값을 수정하는 데 필요한 후크 포인트를 제공합니다. 인터페이스를 사용하면 응용 프로그램이 시작되기 전에 조작할 수 있습니다. 자세한 내용은 시작하기 전에 환경 또는 응용 프로그램 사용자 지정컨텍스트를 참조하십시오.EnvironmentEnvironmentPostProcessorEnvironment

자격 증명과 암호를 저장하는 안전한 방법을 찾고 있다면 스프링 클라우드 볼트 프로젝트는 HashiCorp Vault에외부화된 구성을 저장하는 지원을 제공합니다.

4.2.7. 속성 대신 YAML 사용

YAML은 JSON의 슈퍼셋이며, 따라서 계층 구성 데이터를 지정하는 편리한 형식입니다. 클래스경로에 스네이크YAML 라이브러리가 있을 때마다 YAML을 자동으로 지원합니다.SpringApplication

  "스타터"를 사용하는 경우, 스네이크YAML은 자동으로 에서 제공됩니다. spring-boot-starter
로딩 YAML

스프링 프레임워크는 YAML 문서를 로드하는 데 사용할 수 있는 두 가지 편리한 클래스를 제공합니다. YAML을 로드하고 YAML을 로로드합니다.YamlPropertiesFactoryBeanPropertiesYamlMapFactoryBeanMap

예를 들어 다음 YAML 문서를 고려하십시오.

environments:
    dev:
        url: https://dev.example.com
        name: Developer Setup
    prod:
        url: https://another.example.com
        name: My Cool App

앞의 예제는 다음 속성으로 변환됩니다.

environments.dev.url=https://dev.example.com
environments.dev.name=Developer Setup
environments.prod.url=https://another.example.com
environments.prod.name=My Cool App

YAML 목록은 디레퍼가 있는 속성 키로 표시됩니다. 예를 들어 다음 YAML을 고려하십시오.[index]

my:
   servers:
       - dev.example.com
       - another.example.com

앞의 예제는 다음 속성으로 변환됩니다.

my.servers[0]=dev.example.com
my.servers[1]=another.example.com

스프링 부트의 유틸리티(이는 해당)를 사용하여 이러한 속성에 바인딩하려면 형식(또는)의 대상 빈에 속성을 가져야 하며 세터를 제공하거나 변경할 수 있는 값으로 초기화해야 합니다. 예를 들어 다음 예제는 이전에 표시된 속성에 바인딩됩니다.Binder@ConfigurationPropertiesjava.util.ListSet

@ConfigurationProperties(prefix="my")
public class Config {

    private List<String> servers = new ArrayList<String>();

    public List<String> getServers() {
        return this.servers;
    }
}
YAML을 스프링 환경의 속성으로 노출

클래스는 YAML을 스프링의 일부로 노출하는 데 사용할 수 있습니다. 이렇게 하면 자리 표시자 구문과 함께 기판을 사용하여 YAML 속성에 액세스할 수 있습니다.YamlPropertySourceLoaderPropertySourceEnvironment@Value

다중 프로필 YAML 문서

키를 사용하여 다음 예제와 같이 문서가 적용되는 시기를 표시하여 단일 파일에 여러 프로필별 YAML 문서를 지정할 수 있습니다.spring.profiles

server:
    address: 192.168.1.100
---
spring:
    profiles: development
server:
    address: 127.0.0.1
---
spring:
    profiles: production & eu-central
server:
    address: 192.168.1.120

앞의 예제에서 프로파일이 활성 상태인 경우 속성은. 마찬가지로 프로파일이 활성 상태인 경우 속성은. 및 프로파일을 사용하지 않으면 속성의 값이 됩니다.developmentserver.address127.0.0.1productioneu-centralserver.address192.168.1.120developmentproductioneu-central192.168.1.100

 

spring.profiles 따라서 간단한 프로파일 이름(예:) 또는 프로필 식을 포함할 수 있습니다. 프로파일 식을 사용하면 예를 들어 보다 복잡한 프로파일 논리를 표현할 수 있습니다. 자세한 내용은 참조 가이드를 확인합니다.productionproduction & (eu-central | eu-west)

응용 프로그램 컨텍스트가 시작될 때 명시적으로 활성화되지 않으면 기본 프로파일이 활성화됩니다. 따라서 다음 YAML에서는 "기본" 프로필에서만 사용할 수 있는 값을 설정합니다.spring.security.user.password

server:
  port: 8000
---
spring:
  profiles: default
  security:
    user:
      password: weak

다음 예제에서는 프로필에 연결되지 않았기 때문에 암호가 항상 설정되어 있으며 필요에 따라 다른 모든 프로필에서 명시적으로 재설정해야 합니다.

server:
  port: 8000
spring:
  security:
    user:
      password: weak

요소를 사용하여 지정된 스프링 프로파일은 문자를 사용하여 선택적으로 부정될 수 있습니다. 부정된 프로파일과 부정되지 않은 프로필이 단일 문서에 모두 지정되면 부정되지 않은 프로필이 하나 이상 일치해야 하며 부정된 프로필이 일치하지 않을 수 있습니다.spring.profiles!

YAML 단점

YAML 파일은 이노싱을 사용하여 로드할 수 없습니다. 따라서 값을 로드해야 하는 경우 속성 파일을 사용해야 합니다.@PropertySource

프로필별 YAML 파일에서 다중 YAML 문서 구문을 사용하면 예기치 않은 동작이 발생할 수 있습니다. 예를 들어 파일에서 다음 구성을 고려합니다.

응용 프로그램-dev.yml
server:
  port: 8000
---
spring:
  profiles: "!test"
  security:
    user:
      password: "secret"

인수를 사용하여 응용 프로그램을 실행하는 경우 "비밀"로 설정될 것으로 예상할 수 있지만 그렇지 않습니다.--spring.profiles.active=devsecurity.user.password

중첩된 문서는 주 파일의 이름이 지정되므로 필터링됩니다. 이미 프로필별 것으로 간주되며 중첩된 문서는 무시됩니다.application-dev.yml

  프로필별 YAML 파일과 여러 YAML 문서를 혼합하지 않는 것이 좋습니다. 그들 중 하나만 사용하는 데 충실하십시오.

4.2.8. 유형 안전 구성 속성

특히 여러 속성으로 작업중이거나 데이터가 본질적으로 계층적인 경우 구성 속성을 삽입하기 위해 이 기조를 사용하는 것이 번거로울 수 있습니다. Spring Boot는 강력하게 입력된 콩이 응용 프로그램의 구성을 관리하고 유효성을 검사할 수 있는 속성으로 작업하는 다른 방법을 제공합니다.@Value("${property}")

자바빈 속성 바인딩

다음 예제와 같이 표준 JavaBean 속성을 선언하는 콩 속성을 바인딩할 수 있습니다.

package com.example;

import java.net.InetAddress;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import org.springframework.boot.context.properties.ConfigurationProperties;

@ConfigurationProperties("acme")
public class AcmeProperties {

    private boolean enabled;

    private InetAddress remoteAddress;

    private final Security security = new Security();

    public boolean isEnabled() { ... }

    public void setEnabled(boolean enabled) { ... }

    public InetAddress getRemoteAddress() { ... }

    public void setRemoteAddress(InetAddress remoteAddress) { ... }

    public Security getSecurity() { ... }

    public static class Security {

        private String username;

        private String password;

        private List<String> roles = new ArrayList<>(Collections.singleton("USER"));

        public String getUsername() { ... }

        public void setUsername(String username) { ... }

        public String getPassword() { ... }

        public void setPassword(String password) { ... }

        public List<String> getRoles() { ... }

        public void setRoles(List<String> roles) { ... }

    }
}

앞의 POJO는 다음 속성을 정의합니다.

  • acme.enabled기본적으로 값을 설정합니다.false
  • acme.remote-address에서 강제 변환할 수 있는 형식이 있습니다.String
  • acme.security.username[ 속성의 이름으로 이름이 결정되는 중첩된 "보안" 개체가 있습니다. 특히 리턴 유형은 전혀 사용되지 않으며.SecurityProperties
  • acme.security.password.
  • acme.security.roles[ 해당 기본값의 컬렉션과 함께 .StringUSER
  속성 파일, YAML 파일, 환경 변수 등을 통해 구성된 스프링 부트에서 사용할 수 있는 클래스에 매핑되는 속성은 공용 API이지만 클래스 자체의 액세스터(getters/setters)는 직접 사용되지 않습니다. @ConfigurationProperties
 

바인딩은 스프링 MVC와 마찬가지로 표준 자바 빈 속성 설명기를 통해 있기 때문에 이러한 배열은 기본 빈 생성기및 getters 및 세터에 의존합니다. 세터는 다음과 같은 경우에 생략될 수 있습니다.

  • 맵은 초기화되는 한 바인더에 의해 변질될 수 있기 때문에 게터가 필요하지만 반드시 세터가 필요한 것은 아닙니다.
  • 컬렉션및 배열은 인덱스(일반적으로 YAML 사용)를 통해 또는 단일 쉼표 구분값(속성)을 사용하여 액세스할 수 있습니다. 후자의 경우 세터가 필수입니다. 이러한 유형에 대해 항상 세터를 추가하는 것이 좋습니다. 컬렉션을 초기화하는 경우 이전 예제와 같이 변경할 수 없는지 확인합니다.
  • 중첩된 POJO 속성이 초기화된 경우(예: 앞의 예제의 필드)는 세터가 필요하지 않습니다. 바인더가 기본 생성기를 사용하여 인스턴스를 즉석에서 만들려면 세터가 필요합니다.Security

어떤 사람들은 프로젝트 롬복을 사용하여 게터와 세터를 자동으로 추가합니다. 컨테이너에서 자동으로 사용하여 개체를 인스턴스화하는 데 사용하므로 Lombok이 이러한 형식에 대한 특정 생성기를 생성하지 않도록 합니다.

마지막으로 표준 Java Bean 속성만 고려되고 정적 속성에 바인딩이 지원되지 않습니다.

생성자 바인딩

이전 섹션의 예제는 다음 예제와 같이 변경할 수 없는 방식으로 다시 작성할 수 있습니다.

package com.example;

import java.net.InetAddress;
import java.util.List;

import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.context.properties.ConstructorBinding;
import org.springframework.boot.context.properties.bind.DefaultValue;

@ConstructorBinding
@ConfigurationProperties("acme")
public class AcmeProperties {

    private final boolean enabled;

    private final InetAddress remoteAddress;

    private final Security security;

    public AcmeProperties(boolean enabled, InetAddress remoteAddress, Security security) {
        this.enabled = enabled;
        this.remoteAddress = remoteAddress;
        this.security = security;
    }

    public boolean isEnabled() { ... }

    public InetAddress getRemoteAddress() { ... }

    public Security getSecurity() { ... }

    public static class Security {

        private final String username;

        private final String password;

        private final List<String> roles;

        public Security(String username, String password,
                @DefaultValue("USER") List<String> roles) {
            this.username = username;
            this.password = password;
            this.roles = roles;
        }

        public String getUsername() { ... }

        public String getPassword() { ... }

        public List<String> getRoles() { ... }

    }

}

이 설정에서 부속기는 생성자 바인딩을 사용해야 함을 나타내는 데 사용됩니다. 즉, 바인더는 바인딩하려는 매개 변수가 있는 생성기를 찾을 것으로 예상됩니다.@ConstructorBinding

클래스의 중첩 된 멤버 (예: 위의 예제)도 생성자 통해 바인딩됩니다.@ConstructorBindingSecurity

기본 값을 사용하여 지정할 수 있으며 누락된 속성의 대상 유형에 대한 값을 강제로 변환하기 위해 동일한 변환 서비스가 적용됩니다. 기본적으로 속성에 바인딩되지 않으면 인스턴스에 대한 값이 포함됩니다. 속성이 바인딩되지 않은 경우에도 null이 아닌 인스턴스를 반환하려면 빈 음표를 사용하여 이렇게 할 수 있습니다.@DefaultValueStringSecurityAcmePropertiesnullsecuritySecurity@DefaultValue

package com.example;
import java.net.InetAddress;
import java.util.List;

import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.context.properties.ConstructorBinding;
import org.springframework.boot.context.properties.bind.DefaultValue;

@ConstructorBinding
@ConfigurationProperties("acme")
public class AcmeProperties {

    private final boolean enabled;

    private final InetAddress remoteAddress;

    private final Security security;

    public AcmeProperties(boolean enabled, InetAddress remoteAddress, @DefaultValue Security security) {
        this.enabled = enabled;
        this.remoteAddress = remoteAddress;
        this.security = security;
    }
}
  생성자 바인딩을 사용하려면 클래스를 사용하거나 구성 속성 검색을 사용하도록 설정해야 합니다. 일반 스프링 메커니즘(예:)에 의해 생성된 콩을 사용하여 생성자 바인딩을 사용할 수 없습니다. 콩, 방법을 통해 만든 콩 또는 콩을 사용하여로드 @EnableConfigurationProperties@Component@Bean@Import)
  클래스에 대해 두 개 이상의 생성자가 있는 경우 바인딩해야 하는 생성자에서 직접 사용할 수도 있습니다. @ConstructorBinding
@ConfigurationProperties 인트윗된 형식 사용

Spring Boot는 유형을 바인딩하고 빈으로 등록하는 인프라를 제공합니다. 클래스별로 구성 속성을 사용하도록 설정하거나 구성 요소 검색과 유사한 방식으로 작동하는 구성 속성 검색을 사용하도록 설정할 수 있습니다.@ConfigurationProperties

예를 들어 자체 자동 구성을 개발하거나 조건부로 사용하도록 설정하려는 경우와 같은 추가 클래스가 검색에 적합하지 않을 수 있습니다. 이러한 경우 부조를 사용하여 처리할 형식 목록을 지정합니다. 다음 예제와 같이 모든 클래스에서 수행할 수 있습니다.@ConfigurationProperties@EnableConfigurationProperties@Configuration

@Configuration(proxyBeanMethods = false)
@EnableConfigurationProperties(AcmeProperties.class)
public class MyConfiguration {
}

구성 속성 검색을 사용하려면 응용 프로그램에 추가합니다. 일반적으로 에 추가되지만 모든 클래스에 추가할 수 있습니다. 기본적으로 스캐닝은 어노션을 선언하는 클래스 패키지에서 발생합니다. 스캔할 특정 패키지를 정의하려면 다음 예제와 같이 이렇게 할 수 있습니다.@ConfigurationPropertiesScan@SpringBootApplication@Configuration

@SpringBootApplication
@ConfigurationPropertiesScan({ "com.example.app", "org.acme.another" })
public class MyApplication {
}
 

콩이 구성 속성 스캐닝 또는 통해 등록되면 콩에는 기존 이름이 있습니다: 비도에 지정된 환경 키 접두사는 어디에 있으며 콩의 완전한 자격을 갖춘 이름입니다. 이노칭이 접두사를 제공하지 않는 경우 콩의 정식 이름만 사용됩니다.@ConfigurationProperties@EnableConfigurationProperties<prefix>-<fqn><prefix>@ConfigurationProperties<fqn>

위의 예제의 콩 이름은 .acme-com.example.AcmeProperties

We recommend that only deal with the environment and, in particular, does not inject other beans from the context. For corner cases, setter injection can be used or any of the interfaces provided by the framework (such as if you need access to the ). If you still want to inject other beans using the constructor, the configuration properties bean must be annotated with and use JavaBean-based property binding.@ConfigurationProperties*AwareEnvironmentAwareEnvironment@Component

Using @ConfigurationProperties-annotated types

This style of configuration works particularly well with the external YAML configuration, as shown in the following example:SpringApplication

# application.yml

acme:
    remote-address: 192.168.1.1
    security:
        username: admin
        roles:
          - USER
          - ADMIN

# additional configuration as required

To work with beans, you can inject them in the same way as any other bean, as shown in the following example:@ConfigurationProperties

@Service
public class MyService {

    private final AcmeProperties properties;

    @Autowired
    public MyService(AcmeProperties properties) {
        this.properties = properties;
    }

    //...

    @PostConstruct
    public void openConnection() {
        Server server = new Server(this.properties.getRemoteAddress());
        // ...
    }

}
  또한 IdEs에서 사용할 수 있는 메타데이터 파일을 생성하여 키에 대한 자동 완성을 제공할 수도 있습니다. 자세한 내용은 부록을 참조하십시오. @ConfigurationProperties
타사 구성

클래스에 인음부로 사용하는 것 뿐만 아니라 공용 메서드에서도 사용할 수 있습니다. 이렇게 하면 컨트롤 이외 쪽에 있는 타사 구성 요소에 속성을 바인딩하려는 경우에 특히 유용할 수 있습니다.@ConfigurationProperties@Bean

속성에서 콩을 구성하려면 다음 예제와 같이 콩 등록에 추가합니다.Environment@ConfigurationProperties

@ConfigurationProperties(prefix = "another")
@Bean
public AnotherComponent anotherComponent() {
    ...
}

접두사로 정의된 모든 JavaBean 속성은 이전 예제와 유사한 방식으로 해당 콩에 매핑됩니다.anotherAnotherComponentAcmeProperties

릴렉스 바인딩

스프링 부트은 콩에 바인딩 속성에 대한 몇 가지 편안한 규칙을 사용하므로 속성 이름과 콩 속성 이름 사이에 정확한 일치가 필요하지 않습니다. 이 유용한 일반적인 예로는 대시 구분된 환경 속성(예: 바인딩)과 대문자환경 속성(예: 바인딩)이 있습니다.Environment@ConfigurationPropertiesEnvironmentcontext-pathcontextPathPORTport

예를 들어 다음 클래스를 고려하십시오.@ConfigurationProperties

@ConfigurationProperties(prefix="acme.my-project.person")
public class OwnerProperties {

    private String firstName;

    public String getFirstName() {
        return this.firstName;
    }

    public void setFirstName(String firstName) {
        this.firstName = firstName;
    }

}

위의 코드를 사용하면 다음 속성 이름을 모두 사용할 수 있습니다.

Table 5. relaxed binding
속성 참고

acme.my-project.person.first-name

케밥 케이스, 이는 에 사용 하 여 사용 하 여 사용 하 여 좋습니다..properties.yml

acme.myProject.person.firstName

표준 낙타 케이스 구문.

acme.my_project.person.first_name

사용 및 파일에 사용하기위한 대체 형식인 표기법에 밑줄이 있습니다..properties.yml

ACME_MYPROJECT_PERSON_FIRSTNAME

시스템 환경 변수를 사용할 때 권장되는 대문자 형식입니다.

  이노션의 값은 케밥 케이스에 있어야 합니다(소문자 및 이와 같이 구분). prefix-acme.my-project.person
Table 6. relaxed binding rules per property source
속성 소스 간단한 목록

속성 파일

낙타 케이스, 케밥 케이스 또는 표기표 강조

쉼표 구분값 사용 또는 쉼표 구분된 표준 목록 구문[ ]

YAML 파일

낙타 케이스, 케밥 케이스 또는 표기표 강조

표준 YAML 목록 구문 또는 쉼표 분리 값

환경 변수

대문자 형식은 디리미터로 강조 표시됩니다(환경 변수의 바인딩참조).

밑줄로 둘러싸인 숫자 값(환경 변수의 바인딩 참조))`

시스템 속성

낙타 케이스, 케밥 케이스 또는 표기표 강조

쉼표 구분값 사용 또는 쉼표 구분된 표준 목록 구문[ ]

  가능하면 속성이 소문자 케밥 형식으로 저장됩니다. my.property-name=acme
바인딩 지도

속성에 바인딩할 때 소문자 알파 숫자 문자 이외의 다른 문자가 포함되어 있거나 원래 값이 보존되도록 괄호 표기표를 사용해야 합니다. 키가 로 둘러싸여 있지 않은 경우 알파 숫자가 아니거나 제거된 문자입니다. 예를 들어 다음 속성을 다음과 같은 속성에 바인딩하는 것이 좋습니다.Mapkey-[]-Map

acme:
  map:
    "[/key1]": value1
    "[/key2]": value2
    /key3: value3

위의 속성은 맵의 키로, 그리고 있는 속성에 바인딩됩니다.Map/key1/key2key3

  YAML 파일의 경우 대괄호는 키가 제대로 구문 분석될 수 있도록 따옴표로 둘러싸여야 합니다.
환경 변수에서 바인딩

대부분의 운영 체제는 환경 변수에 사용할 수 있는 이름에 대해 엄격한 규칙을 적용합니다. 예를 들어 Linux 셸 변수에는 문자(to 또는 to), 숫자(to) 또는 밑줄 문자()만 포함될 수 있습니다. 규칙에 따라 유닉스 쉘 변수는 UPPERCASE에도 이름을 갖습니다.azAZ09_

스프링 부트의 편안한 바인딩 규칙은 가능한 한 이러한 명명 제한과 호환되도록 설계되었습니다.

표준 형식의 속성 이름을 환경 변수 이름으로 변환하려면 다음 규칙을 따를 수 있습니다.

  • 점()을 밑줄()으로 바꿉니다.._
  • 대시()를 제거합니다.-
  • 대문자로 변환합니다.

예를 들어 구성 속성은 라는 환경 변수입니다.spring.main.log-startup-infoSPRING_MAIN_LOGSTARTUPINFO

  밑줄을 사용하여 속성 이름의 대시를 대체할 수 없습니다. 위의 예제와 함께 사용하려고 하면 값이 바인딩되지 않습니다. SPRING_MAIN_LOG_STARTUP_INFO

개체 목록에 바인딩할 때도 환경 변수를 사용할 수 있습니다. 요소에 바인딩하려면 요소 번호를 변수 이름의 밑줄로 둘러싸야 합니다.List

예를 들어 구성 속성은 라는 환경 변수를 사용합니다.my.acme[0].otherMY_ACME_0_OTHER

복잡한 형식 병합

목록이 둘 이상의 장소에서 구성되면 전체 목록을 대체하여 재정의하는 작업을 재정의합니다.

예를 들어 기본적으로 있는 개체와 특성을 가정합니다. 다음 예제에서 개체 목록이 노출됩니다.MyPojonamedescriptionnullMyPojoAcmeProperties

@ConfigurationProperties("acme")
public class AcmeProperties {

    private final List<MyPojo> list = new ArrayList<>();

    public List<MyPojo> getList() {
        return this.list;
    }

}

다음 구성을 고려하십시오.

acme:
  list:
    - name: my name
      description: my description
---
spring:
  profiles: dev
acme:
  list:
    - name: my another name

프로파일이 활성화되어 있지 않은 경우 이전에 정의된 항목과 같이 하나의 항목이 포함되어 있습니다. 그러나 프로파일을 사용하도록 설정하면 여전히 하나의 항목(이름과 설명)만 포함됩니다. 이 구성은 목록에 두 번째 인스턴스를 추가하지 않으며 항목을 병합하지 않습니다.devAcmeProperties.listMyPojodevlistmy another namenullMyPojo

a가 여러 프로파일에 지정되면 우선 순위가 가장 높은 프로파일(그리고 그 프로파일만)이 사용됩니다. 다음 예제를 고려하십시오.List

acme:
  list:
    - name: my name
      description: my description
    - name: another name
      description: another description
---
spring:
  profiles: dev
acme:
  list:
    - name: my another name

앞의 예제에서 프로파일이 활성 상태인 경우 하나의 항목(이름 및 설명)이 포함됩니다. YAML의 경우 쉼표 구분 목록과 YAML 목록을 모두 목록의 내용을 완전히 재정의하는 데 사용할 수 있습니다.devAcmeProperties.listMyPojomy another namenull

속성의 경우 여러 소스에서 가져온 속성 값으로 바인딩할 수 있습니다. 그러나 여러 소스의 동일한 속성에 대해 우선 순위가 가장 높은 속성이 사용됩니다. 다음 예제에서 다음을 노출합니다.MapMap<String, MyPojo>AcmeProperties

@ConfigurationProperties("acme")
public class AcmeProperties {

    private final Map<String, MyPojo> map = new HashMap<>();

    public Map<String, MyPojo> getMap() {
        return this.map;
    }

}

다음 구성을 고려하십시오.

acme:
  map:
    key1:
      name: my name 1
      description: my description 1
---
spring:
  profiles: dev
acme:
  map:
    key1:
      name: dev name 1
    key2:
      name: dev name 2
      description: dev description 2

프로파일이 활성화되어 있지 않은 경우 키가 있는 항목(이름 및 설명)이 포함됩니다. 그러나 프로파일을 사용하도록 설정하면 키(이름과 설명 포함)와 (이름과 설명)이 있는 두 개의 항목이 포함되어 있습니다( 이름과 설명).devAcmeProperties.mapkey1my name 1my description 1devmapkey1dev name 1my description 1key2dev name 2dev description 2

  앞의 병합 규칙은 YAML 파일뿐만 아니라 모든 속성 소스의 속성에 적용됩니다.
속성 변환

스프링 부트은 콩에 바인딩할 때 외부 응용 프로그램 속성을 올바른 유형으로 강제변환하려고 시도합니다. 사용자 지정 형식 변환이 필요한 경우 콩(명명된 콩) 또는 사용자 지정 속성 편집기(콩을 통해) 또는 사용자 지정(bean 정의로 인칭)을 제공할 수 있습니다.@ConfigurationPropertiesConversionServiceconversionServiceCustomEditorConfigurerConverters@ConfigurationPropertiesBinding

  응용 프로그램 수명 주기 중에 이 콩이 매우 일찍 요청되기 때문에 사용 하는 종속성을 제한 해야 합니다. 일반적으로 필요한 종속성은 생성 시점에 완전히 초기화되지 않을 수 있습니다. 구성 키 강제 변환에 필요하지 않고 자격이 있는 사용자 지정 변환기만 으로 지정이름을 바꿀 수 있습니다. ConversionServiceConversionService@ConfigurationPropertiesBinding
시간 변환

스프링 부트는 지속 시간을 표현하는 데 전념합니다. 속성을 노출하는 경우 응용 프로그램 속성에서 다음 형식을 사용할 수 있습니다.java.time.Duration

  • 일반 표현(밀리초를 기본 단위로 사용하지 않는 한 기본 장치로 사용)long@DurationUnit
  • java.time.Duration에서 사용하는 표준 ISO-8601 형식
  • 값과 단위가 결합되는 보다 읽기 쉬운 형식(예: 10초를 의미합니다)10s

다음 예제를 고려하십시오.

@ConfigurationProperties("app.system")
public class AppSystemProperties {

    @DurationUnit(ChronoUnit.SECONDS)
    private Duration sessionTimeout = Duration.ofSeconds(30);

    private Duration readTimeout = Duration.ofMillis(1000);

    public Duration getSessionTimeout() {
        return this.sessionTimeout;
    }

    public void setSessionTimeout(Duration sessionTimeout) {
        this.sessionTimeout = sessionTimeout;
    }

    public Duration getReadTimeout() {
        return this.readTimeout;
    }

    public void setReadTimeout(Duration readTimeout) {
        this.readTimeout = readTimeout;
    }

}

30초의 세션 시간 시간을 지정하려면 모두 동일합니다. 500ms의 읽기 시간 시간은 다음 양식 중 에서 지정할 수 있습니다.30PT30S30s500PT0.5S500ms

지원되는 단위를 사용할 수도 있습니다. 다음은 다음과 같습니다.

  • ns 나노초 동안
  • us 마이크로초 동안
  • ms 밀리초 동안
  • s 초 동안
  • m
  • h 시간 동안
  • d 며칠 동안

기본 단위는 밀리초이며 위의 샘플에 나와 있는 대로 재정의할 수 있습니다.@DurationUnit

  속성을 업그레이드하는 경우 밀리초가 아닌 경우 단위(사용)를 정의해야 합니다. 이렇게 하면 훨씬 더 풍부한 형식을 지원하면서 투명한 업그레이드 경로를 제공합니다. Long@DurationUnit
변환 기간

스프링 부트은 지속 시간 외에도 유형으로도 작동할 수 있습니다. 다음 형식은 응용 프로그램 속성에 사용할 수 있습니다.java.time.Period

  • 일반 표현(지정되지 않은 경우 일 수를 기본 단위로 사용)int@PeriodUnit
  • java.time.period에서 사용하는 표준 ISO-8601 형식
  • 값과 단위 쌍이 결합되는 간단한 형식(예: 1년 3일을 의미)1y3d

다음 단위는 간단한 형식으로 지원됩니다.

  • y 년 동안
  • m 개월 동안
  • w 몇 주 동안
  • d 며칠 동안
  이 유형은 실제로 주 수를 저장하지 않습니다, 그것은 단순히 "7 일"을 의미하는 바로 가기입니다. java.time.Period
데이터 크기 변환

Spring Framework에는 바이트에서 크기를 표현하는 값 형식이 있습니다. 속성을 노출하는 경우 응용 프로그램 속성에서 다음 형식을 사용할 수 있습니다.DataSizeDataSize

  • 일반 표현(바이트를 기본 단위로 사용하는 경우).long@DataSizeUnit
  • 값과 단위가 결합되는 보다 읽기 쉬운 형식(예: 10메가바이트를 의미)10MB

다음 예제를 고려하십시오.

@ConfigurationProperties("app.io")
public class AppIoProperties {

    @DataSizeUnit(DataUnit.MEGABYTES)
    private DataSize bufferSize = DataSize.ofMegabytes(2);

    private DataSize sizeThreshold = DataSize.ofBytes(512);

    public DataSize getBufferSize() {
        return this.bufferSize;
    }

    public void setBufferSize(DataSize bufferSize) {
        this.bufferSize = bufferSize;
    }

    public DataSize getSizeThreshold() {
        return this.sizeThreshold;
    }

    public void setSizeThreshold(DataSize sizeThreshold) {
        this.sizeThreshold = sizeThreshold;
    }

}

10메가바이트의 버퍼 크기를 지정하려면 해당합니다. 256바이트의 크기 임계값을 로 지정하거나 로 지정할 수 있습니다.1010MB256256B

지원되는 단위를 사용할 수도 있습니다. 다음은 다음과 같습니다.

  • B 바이트용
  • KB 킬로바이트용
  • MB 메가바이트용
  • GB 기가바이트용
  • TB 테라바이트용

기본 단위는 바이트이며 위의 샘플에 설명된 대로 재정의할 수 있습니다.@DataSizeUnit

  속성을 업그레이드하는 경우 바이트가 아닌 경우 단위(사용)를 정의해야 합니다. 이렇게 하면 훨씬 더 풍부한 형식을 지원하면서 투명한 업그레이드 경로를 제공합니다. Long@DataSizeUnit
@ConfigurationProperties 유효성 검사

스프링 부트은 스프링의 성약에 추가될 때마다 클래스의 유효성을 검사하려고 시도합니다. 구성 클래스에서 JSR-303 제약 조건 주석을 직접 사용할 수 있습니다. 이렇게 하려면 다음 예제와 같이 준수하는 JSR-303 구현이 클래스 경로에 있는지 확인하고 다음 예제와 같이 제약 조건 주석을 필드에 추가합니다.@ConfigurationProperties@Validatedjavax.validation

@ConfigurationProperties(prefix="acme")
@Validated
public class AcmeProperties {

    @NotNull
    private InetAddress remoteAddress;

    // ... getters and setters

}
  구성 속성을 만드는 메서드에 대해 항목별로 추가하여 유효성 검사를 트리거할 수도 있습니다. @Bean@Validated

속성이 발견되지 않더라도 중첩된 속성에 대해 유효성 검사가 항상 트리거되도록 하려면 관련 필드에 에 추가되어야 합니다. 다음 예제는 앞의 예제를 기반으로 합니다.@ValidAcmeProperties

@ConfigurationProperties(prefix="acme")
@Validated
public class AcmeProperties {

    @NotNull
    private InetAddress remoteAddress;

    @Valid
    private final Security security = new Security();

    // ... getters and setters

    public static class Security {

        @NotEmpty
        public String username;

        // ... getters and setters

    }

}

또한 bean 정의라는 생성하여 사용자 지정 스프링을 추가할 수도 있습니다. 메서드를 선언 해야 합니다. 구성 속성 유효성 검사기는 응용 프로그램의 수명 주기 초기에 매우 일찍 만들어지며 메서드를 정적으로 선언하면 클래스를 인스턴스화하지 않고도 콩을 만들 수 있습니다. 이렇게 하면 초기 인스턴스화로 인해 발생할 수 있는 문제가 발생하지 않습니다.ValidatorconfigurationPropertiesValidator@Beanstatic@Bean@Configuration

  모듈에는 모든 콩을 노출하는 끝점이 포함되어 있습니다. 웹 브라우저를 가리키거나 해당 JMX 끝점을 사용합니다. 자세한 내용은"프로덕션 준비 기능"섹션을 참조하십시오. spring-boot-actuator@ConfigurationProperties/actuator/configprops
@ConfigurationProperties vs. @Value

이 별표는 핵심 컨테이너 기능이며 형식 안전 구성 속성과 동일한 기능을 제공하지 않습니다. 다음 표에서는 다음에 의해 지원되는 기능을 요약하고 다음과 같습니다.@Value@ConfigurationProperties@Value

기능 @ConfigurationProperties @Value

편안한 바인딩

한정(아래 참고 사항 참조)

메타 데이터 지원

아니요

SpEL 평가

아니요

고유한 구성 요소에 대한 구성 키 집합을 정의하는 경우 에 추가된 POJO에 그룹화하는 것이 좋습니다. 이렇게 하면 자신의 콩에 주입할 수 있는 구조화된 유형 안전 물체가 제공됩니다.@ConfigurationProperties

사용하려는 경우 정식 양식(소문자만 사용하는 케밥 케이스)을 사용하여 속성 이름을 참조하는 것이 좋습니다. 이렇게 하면 스프링 부트이 바인딩할 때와 동일한 논리를 사용할 수 있습니다. 예를 들어 시스템 환경뿐만 아니라 파일에서 픽업및 양식이 제공됩니다. 대신 사용하면 고려되지 않습니다.@Value@ConfigurationProperties@Value("{demo.item-price}")demo.item-pricedemo.itemPriceapplication.propertiesDEMO_ITEMPRICE@Value("{demo.itemPrice}")demo.item-priceDEMO_ITEMPRICE

마지막으로 식을 작성할 수 있지만 이러한 식은 응용 프로그램 속성 파일에서처리되지 않습니다.SpEL@Value

Spring Boot Reference Documentation

Phillip Webb, Dave Syer, Josh Long, Stéphane Nicoll, Rob Winch, Andy Wilkinson, Marcel Overdijk, Christian Dupuis, Sébastien Deleuze, Michael Simons, Vedran Pavić, Jay Bryant, Madhura Bhave, Eddú Meléndez, Scott Frederick

2.3.1.RELEASE

Copyright © 2012-2020

Copies of this document may be made for your own use and for distribution to others, provided that you do not charge any fee for such copies and further provided that each copy contains this Copyright Notice, whether distributed in print or electronically.

 

출처 : https://docs.spring.io/spring-boot/docs/2.3.1.RELEASE/reference/htmlsingle/#boot-features-external-config

반응형