kok202
스프링 부트 강의 정리 (8~10 : Properties 읽어들이기)

2019. 4. 21. 01:39[공부] 영상/스프링 부트 강의

스프링 부트는 설정파일을 밖으로 빼낼 수 있게 해져있다. properties, yml, Environment, command line 등을 사용하여 정의할 수 있다. 정의된 설정 값은 @Value로 주입받거나 스프링이 제공하는 Environment interface로 접근할 수 있다. 값을 주입 받는 방법은 @Value("${name}") 이다.

 

설정값 우선순위

1. spring-boot-devtools를 사용할 경우 ~/.spring-boot-devtools.properties

2. @TestPropertySource

3. @SpringBootTest 

 

여기서부터 실질적으로 사용하는 값들이다.

4. Command line argument

5. Command line argument 를 SPRING_APPLICATION_JSON 으로 줄경우

6. ServletConfig 의 init 

7. ServletContext

8. JNDI attribute

9. 시스템 변수 (-D 로 시작하는 것 ex. -Dspring.profiels.active=local)

10. OS 환경 변수

11. random.*에 있는RandomValuePropertySource 

12. application[-profiles].yml 또는 properties  (패키지 jar 밖에 있는 properties)

13. application[-profiles].yml 또는 properties (패키지 jar 안에 있는 properties)

14. application.yml 또는 properties (패키지 jar 밖에 있는 properties)

15. application.yml 또는 properties (패키지 jar 안에 있는 properties)

16. @Configuration 클래스에 명시한 @PropertySource

17. 스프링에 있는 DefaultProperty

 

패키지 jar 밖에 있는 properties?

jar 파일을 실행하는 디렉토리에 /config 디렉토리가 있을 경우 그 안에 존재하는 properties, yml파일

 

예제

resource/application.yml

name: hello

Run - Edit configuration

-Dname=world

Command line

java -jar target/MyApplication0-0-1-SNAPSHOT.jar --name=kok202

코드

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

name에 주입되는 값은 kok202 이다. 

kok202 > world > hello 수준으로 우선순위가 결정된다.

 

config 설정은 설정 방법이 무수히 많다.

가능하면 괜히 custom 하게 사용하지 말고 많이 쓰는 방법을 따라하자

 

 

 

YML : Json 의 subset

Spring 은 SnakeYML이라는 라이브러리를 사용하는데, SnakeYML은 Spring boot 를 의존성 추가하면 알아서 추가가 된다. 참조 : https://kok202.tistory.com/51

 

[2019.03.05] YAML

YAML - 읽기 쉽다. - 데이터 포맷중 하나다. - Key - value 구조다. - JSON은 yaml의 일종이다. member: id: "kok202" pwd: null male: true money: 1000 email: &connection "kok202@naver.com" description: | H..

kok202.tistory.com

스프링 부트는 내부적으로 YML 파일을 읽어서 Properties로 바꾸고 궁극적으로 이를 Environment 로 들어가게된다.

@Value 어노테이션은 그냥 Environment에 있는 값을 불러오는 것이다. YML 파일을 읽어들이는 것이 아니다.

그리고 YML 파일을 읽어서 properties로 바꾸기 때문에 같은 이름의 yml 파일과 properties 파일이 동시에 있을 경우 yml이 우선순위가 좀더 높다.

spring.profiles를 쓰면 development, local 환경을 분리할 수 있다.

https://kok202.tistory.com/114?category=782902

 

스프링 부트 개발환경 로컬환경 분리

application.yml 에 profile을 dev와 local 로 분할 spring: profiles: development ... --- spring: profiles: local ... 로컬환경으로 돌리고 싶을 경우 Run - Edit configurations -> Configuration ->VM optio..

kok202.tistory.com

 

YML 파일로 오브젝트를 주입 받을 수도 있다. 단 주의 사항이 있다.

1. 오브젝트로 주입받으려는 클래스가 기본 생성자가 없으면 안된다.

2. @Value 로는 주입 받을 수 없다. @ConfigurationProperties를 사용해야한다.

 

 

 

 

 

@ConfigurationProperties("YML 객체이름")

-> YML 파일에서 읽어들이길 원하는 특정 오브젝트만 가져올 수 있다.

-> Type safe 하다.

spring:
    profiles: development
myHost:
    url: kok202.tistory.com
    port: 8080
    user:
        id: scott
        pwd: tiger
@Getter
@Setter
@Component
@ConfigurationProperties("myHost")
public class MyConfiguration{
    private String url;
    private int port;
    private User user;
}
@Data
public class User{
    private String id;
    private String pwd;
}

참고 : @ConfigurationProperties 는 relaxed binding 규칙으로 바인딩을 알아서 해준다. @Value는 안된다.

relaxed binding 규칙 : 아래 4개의 hello world 는 같은 변수 이름으로 묶인다. 

camel case helloWorld
kebab case (or snake case) hello-world
underscore case hello_world
upper case HELLO_WORLD

@ConfigurationProperties 하여 선언한 클래스를 Bean으로 등록하는 방법은 크게 두가지가 있을 것이다.

1. MyConfiguration 클래스에 @Component를 쓴다.

2. MyConfiguration 클래스를 @Autowired 하는 클래스에서 @EnableConfigurationProperties(MyConfiguration.class)를 해줘서 Bean파일로 등록시키고주입 받는 방법이있다. 

방법은 무궁무진한데 가능하면 1번을 쓰자.

 

 

 

 

 

* 왜 객체를 주입 받으려면 @Value는 안되고 @ConfigurationProperties는 되는가?

@Value는 그냥 단순히 Environment에 있는 값을 불러와서 주입하는 방식이다. 

예제에 있는 yml 파일은 다음과 같이 properites로 변환이 되고 이대로 environment에 들어간다.

spring.profiles=development
myhost.url=kok202.tistory.com
myhost.port=8080
myhost.user.id=scott
myhost.user.pwd=tiger

이 상황에서 

@Value("${myhost.user}")
private User user;

한다고 해봤자 environment에는 myhost.user가 존재하지 않기 때문이다. 반면 @ConfigurationProperties는 yml 파일을 serialize 해서 MyConfiguration으로 맵핑해주는 형태인 것으로 추측된다. 그렇기 때문에 객체로 읽어들일 수 있는 것 같다. 더불어 그래서 Type safe 하다고 말하는 듯 싶다. 스프링 부트는 그래서 @ConfigurationProperties를 사용하는 것을 추천한다.

 

 

 

 

 

@ConfigurationProperties의 장점

1. ThirdParty 라이브러리에 있는 properties 값을 가져올 수 있다.

@Bean
@ConfigurationProperties
public ThirdPartyProperties thirdPartyProperties(){
	return new ThirdPartyProperties();
}

 

2. Type safe하다. 

- Object를 properties로 받아올 수 있다.

- Duration 클래스를 이용하면 시계열 데이터를 int나 long이 아니게 값을 불러올 수 있다.

 

 

 

 

 

Validation error 검증하는 어노테이션

@NotEmpty

@Min(0)

@Max(100)

 

 

 

 

 

Properties 파일에 있는 설정 정리

https://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#common-application-properties

 

Spring Boot Reference Guide

 

docs.spring.io