-
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 순서를 사용하는데 순서는 아래와 같습니다.
-
devtools 이 활성화 상태에서 $HOME/.config/spring-boot 디렉토리의 Devtools global settings properties
-
spring-boot-devtools.properties
-
spring-boot-devtools.yaml
-
spring-boot-devtools.yml
-
-
Test 의 @TestPropertySource annotations
-
Test 의 properties 속성. @SpringBootTest 와 application 의 특정 부분을 테스트 하기 위한 test annotations
-
spring-boot-test-autoconfigure 를 통해 '@...Test' annotation 으로 설정되는 것들(@SpringBootTest, @WebMvcTest 등)
-
-
Command line 을 통해 입력된 arguments
-
환경 변수 또는 시스템 속성에 포함된 inline JSON 인 SPRING_APPLICATION_JSON 의 속성
-
ServletConfig 의 초기 파라미터들
-
ServletContext 의 초기 파라미터들
-
java:comp/env 의 JNDI 속성
-
Java 시스템 속성 (System.getProperties())
-
OS 환경 변수
-
random.* 에만 속성이 있는 RandomValuePropertySource - ${random.value} 등으로 접근
-
패키지된 jar 의 외부에 있는 특정 프로필별 application properties (application-{profile}.properties 나 YAML)
-
jar 의 내부에 패키지 되어 있는 특정 프로필별 application properties (application-{profile}.properties 나 YAML)
-
패키지된 jar 의 외부에 있는 Application properties (세부적으로는 아래와 같은 위치의 application.properties 파일을 읽음. 위가 우선순위 높음)
-
현재 디렉토리의 /config 디렉토리
-
현재 디렉토리
-
classpath 의 /config 패키지
-
classpath 의 root
-
-
jar 의 내부에 패지키 되어 있는 Application properties (위와 동일)
-
@Configuration 클래스들의 @PropertySource annotations
-
기본 속성(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'기록해야 기억한다 > Spring' 카테고리의 다른 글
Spring REST 에서의 Global Exception (0) 2021.01.11 Spring Cloud OpenFeign, 그리고 SSL (2) 2020.12.29 스케줄러에 property 주입하기 (0) 2020.12.17 spring boot - 전체 초기화 코드를 넣어보자 (0) 2020.11.14 Spring Boot 분석(구동 원리) (0) 2020.11.14 -