ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • Spring Boot 의 properties
    기록해야 기억한다/Spring 2020. 11. 16. 13:02

    개요

    properties 는 기본이면서도 설정에 가장 많이 사용하게 되는 요소입니다.

    기본적으로는 .properies, .yml 등을 통해 설정할 수 있는데 관련 방법들도 많고 어떻게 써야 효과적인지도 명확하지 않습니다.
    가장 많이 이용하게 되고 실제 유용한 방법들을 정리합니다.


     

    외부화 구성(Externalized Configuration)

    Spring Boot 는 다른 환경에서 동일한 코드로 작업할 수 있도록 구성을 외부화 할 수 있습니다. 
    환경 변수, command-line arguments, 별도의 외부 파일 등을 이용할 수 있는데, 이 때 properties 의 효과가 발휘됩니다. YAML 파일, properties 파일들을 통해 지정된 속성 값은 @Value 주석을 사용하여 Bean 에 직접 주입하거나 Spring 의 Environment 추상화를 통해 접근하거나 @ConfigurationProperties 를 통해 구조화된 객체에 바인딩 할 수 있습니다.

    정의된 값을 환경에 맞게 합리적으로 사용하도록 매우 특별한 PropertySource 순서를 사용하는데 순서는 아래와 같습니다.

     

    1. devtools 이 활성화 상태에서 $HOME/.config/spring-boot 디렉토리의 Devtools global settings properties

      • spring-boot-devtools.properties

      • spring-boot-devtools.yaml

      • spring-boot-devtools.yml

    2. Test 의 @TestPropertySource annotations

    3. Test 의 properties 속성. @SpringBootTest 와 application 의 특정 부분을 테스트 하기 위한 test annotations

      • spring-boot-test-autoconfigure 를 통해 '@...Test' annotation 으로 설정되는 것들(@SpringBootTest, @WebMvcTest 등)

    4. Command line 을 통해 입력된 arguments

    5. 환경 변수 또는 시스템 속성에 포함된 inline JSON 인 SPRING_APPLICATION_JSON 의 속성

    6. ServletConfig 의 초기 파라미터들

    7. ServletContext 의 초기 파라미터들

    8. java:comp/env 의 JNDI 속성

    9. Java 시스템 속성 (System.getProperties())

    10. OS 환경 변수

    11. random.* 에만 속성이 있는 RandomValuePropertySource - ${random.value} 등으로 접근

    12. 패키지된 jar 의 외부에 있는 특정 프로필별 application properties (application-{profile}.properties 나 YAML)

    13.  jar 의 내부에 패키지 되어 있는 특정 프로필별 application properties (application-{profile}.properties 나 YAML)

    14. 패키지된 jar 의 외부에 있는 Application properties (세부적으로는 아래와 같은 위치의 application.properties 파일을 읽음. 위가 우선순위 높음)

      • 현재 디렉토리의 /config 디렉토리

      • 현재 디렉토리

      • classpath 의 /config 패키지

      • classpath 의 root

    15. jar 의 내부에 패지키 되어 있는 Application properties (위와 동일)

    16. @Configuration  클래스들의 @PropertySource annotations

    17. 기본 속성(SpringApplication.setDefaultProperties 를 설정하여 지정)

     

    SPRING_APPLICATION_JSON

    SPRING_APPLICATION_JSON 은 아래와 같이 사용할 수 있습니다.

    $ java -Dspring.application.json='{"key":"value"}' -jar myapp.jar

     

    자리표시자(Placeholders) 를 통한 Properties 이용

    application.properties 의 값은 사용될 때 기존 환경을 통해 필터링되므로 이전에 정의된 값을 다시 사용할 수 있습니다.

    단, 사용되는 값은 반드시 앞서 선언이 되어 있어야 합니다.

    app.name=MyApp
    app.description=${app.name} is a Application Name
    app.detail=${app.description} 's detail


    Application 에서 Properties 접근

    yml, yaml, properties 파일을 통해 선언된 속성 값들은 아래와 같은 방법으로 Properties 에 접근할 수 있습니다.

    • @Value 이용
    • @ConfigurationProperties 이용
    • Environment 클래스 주입

    @ConfigurationProperties 이용

    외부화 구성을 통해 선언된 속성 사용에 대한 주석입니다. 일부 외부 속성 (예 : .properties 파일에서) 을 바인딩하고 유효성을 검사하려면 @Configuration 클래스의 클래스 정의 또는 @Bean 에 이를 추가합니다.

    바인딩은 주석이 추가 된 클래스에서 setter 를 호출하거나 @ConstructorBinding 이 사용 중인 경우 생성자 매개 변수에 바인딩하여 수행되고 @Value와 달리 속성 값이 외부화 구성되기 때문에 SpEL 식은 사용할 수 없습니다.

    # application.yml
    
    acme:    remote-address: 192.168.1.1
    
        security:
    
            username: admin
    
            roles:
    
              - USER
    
              - ADMIN
    
    
    
    # additional configuration as required
    
    ---------------------------------------------------------------
    
    // .properties 에 acme 로 지정된 값들을 클래스로 구성한다.
    
    @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) { ... }
    
        }
    
    }


    외부 설정을 접두어(prefix)로 묶어서 계층 구조, 맵구조를 사용할 수 있다.
    이런 방법으로 얻을 수 있는 점은 아래와 같습니다.

    • 해당 클래스의 필드에 기본 값을 설정하여 기본값을 쉽게 지정할 수 있다.

    • int, double 등 String 이외의 타입을 설정 프로퍼티 클래스의 프로퍼티에 사용할 수 있다. Spring 에서 해당 타입으로 convert 한다.

     

    @Value  이용

    일반적인 사용 사례는 #{systemProperties.myProp} 스타일의 SpEL 표현식을 사용하여 값을 삽입하는 것입니다. 또는 ${my.app.myProp} 스타일의 Placeholders 를 사용하여 값을 삽입할 수 있습니다.

    해당 annotatino 의 실제 처리는 BeanPostProcessor 나 BeanFactoryPostProcessor  에 의해 수행되며 해당 형태들에서는 @Value 를 이용할 수 없습니다.

    import org.springframework.stereotype.*;
    
    import org.springframework.beans.factory.annotation.*;
    
    @Component
    public class MyBean {
    
        @Value("${name}")
        private String name;
        // ...
    }

    Spring 의 관련 클래스에서 @Autowired 같은 주입을 통해 Environment 클래스를 지정하여 환경 변수에 접근할 수 있습니다.

    Environment 클래스 이용

    @Autowired
    private Environment env;
    
    ...
    dataSource.setUrl(env.getProperty("jdbc.url"));
    반응형
    LIST

    댓글

Designed by Tistory.