프로젝트 설정파일

프로젝트 생성시 src/main/resources/application.properties 파일이 생긴다

현지점 기준으로 .properties 형식의 파일 보다 .yml 파일을 더 많이 쓴다.

properties 파일과 yml 파일을 비교해보자

environments.dev.url=http://dev.bar.com
environments.dev.name=Developer Setup
environments.prod.url=http://foo.bar.com
environments.prod.name=My Cool App
environments:
    dev:
        url: http://dev.bar.com
        name: Developer Setup
    prod:
        url: http://foo.bar.com
        name: My Cool App

.yml 의 장점은 단일 파일에 다중설정 이 가능하다

server:
  port: 8881
---
spring:
  profiles: dev
server:
  port: 8882
---
spring:
  profiles: test
server:
  port: 8883
---
spring:
  profiles: prod
server:
  port: 8883

단점은 @PropertySource 사용하여 로딩할수 없다. 하지만 yml 은 메모리에 저장된다. 항상 properties 파일보다 우선순위가 높다.

사용자 지정 매개변수

book.name=SpringCloudInAction
book.author=blaketest

@Value 로 값 불러오기

@Component
public class Book {

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

    // getter setter 생략
}
  • PlaceHolder 방식: ${...}

  • SpEL 방식 : SpEL 란 ? Spring Expression Language , #{...}

application.properties 값 참조

book.name=SpringCloud
book.author=blaketest
book.desc=${book.author}  is writing《${book.name}》

Random 수를 사용가능

# 랜덤 string
com.blake.blog.value=${random.value}
# 랜덤 int
com.blake.blog.number=${random.int}
# 랜덤 long
com.blake.blog.bignumber=${random.long}
# 10 내
com.blake.blog.test1=${random.int(10)}
# 10-20 사이
com.blake.blog.test2=${random.int[10,20]}

Command

java -jar xxx.jar --server.port=8888

처럼 -- 기호를 사용여 application.properties 값을 불러 올수 있다.

properties 파일 멀티 환경 지원

application-{profile}.properties

  • application-dev.properties:개발

  • application-test.properties:테스트

  • application-prod.properties:운영

spring.profiles.active 값에 의하여 어떤 설정파일이 로딩될지 결정된다.

스크립트 작성핼때 고려하면 좋을것 같다.

java -jar xxx.jar --spring.profiles.active=test
java -jar xxx.jar --spring.profiles.active=prod

Spring Boot는 각 속성의 값을 보다 합리적으로 다시 쓸 수 있도록 다음과 같은 특별한 속성 로딩 순서를 사용합니다.

아래 내용들은 높은 우선순으로 나열 한다.

1. 명령줄에 들어오는 매개 변수입니다.

2. SPRING_APPLICATION_JSON의 속성.SPRING_APPLICATION_JSON은 시스템 환경 변수에 JSON 형식으로 구성된 콘텐츠이다.

3. java:comp/env의 JNDI 속성

4. Java의 시스템 속성은 System.getProperties( )를 통해 얻을 수 있음.

5. 운영 체제의 환경 변수

6. random.*을 통해 구성된 임의 속성

7. 현재 응용 프로그램 jar 패키지에 있는 다른 {profile} 환경에 대한 설정 파일. 예를 들어 application-{profile}.properties 또는 YAML 정의 설정 파일.

8. 현재 응용 프로그램 jar 패키지에 있는 {profile} 환경에 대한 설정 파일 내용. 예를 들어 application-{profile}.properties 또는 YAML 정의 설정 파일.

9. 현재 응용 프로그램 jar 패키지 밖에 있는 application.properties와 YAML 설정 내용.

10. 현재 응용 프로그램 jar 패키지에 있는 application.properties와 YAML 설정 내용.

11. @Configuration 주기에 의해 수정된 클래스에서 @PropertySource 주기에 의해 정의된 속성.

12. SpringApplication.setDefaultProperties를 사용하여 정의된 기본 속성 적용

항목 7과 9는 모두 애플리케이션 jar 패키지 외부에서 구성 파일을 읽는 것을 볼 수 있으므로 외부 구성을 구현하는 원리는 여기에서 잘라내어 jar 패키지 내의 구성 내용을 대체하는 외부 구성 파일의 로딩 위치를 지정하는 것.이러한 실현을 통해 우리의 프로젝트 설정들은 깔끔해지고 환경별로 개발에 필요한 설정들을 관리하면 유지하는데 더 효율있고 편리하다.

Springboot 2.x 특징

Spring Boot 2.0에서 구성 속성을 로드할 때 1.x 버전에서와 같이 특수 문자를 제거하는 것 외에도 구성을 모두 소문자로 일치시키고 로드한다.그러므로 아래의 4가지 배치 방식은 모두 동등하다고면 된다다.

  • properties

spring.jpa.databaseplatform=mysql
spring.jpa.database-platform=mysql
spring.jpa.databasePlatform=mysql
spring.JPA.database_platform=mysql
  • yaml

spring:
  jpa:
    databaseplatform: mysql
    database-platform: mysql
    databasePlatform: mysql
    database_platform: mysql

- 로 문자를 분리해라! 예시:spring.jpa.database-platform=mysql

  • List 타입

spring.my-example.url[0]=http://example.com
spring.my-example.url[1]=http://spring.io
spring.my-example.url=http://example.com,http://spring.io
spring:
  my-example:
    url:
      - http://example.com
      - http://spring.io
spring:
  my-example:
    url: http://example.com, http://spring.io

주의: Springboot2.0 이후 버전은 배열에 대한 설정은 꼭 연속된 배열이 여야 한다. 아닐시UnboundConfigurationPropertiesException 예외 발생한다.

Springboot 1.x 에서는 아래와 같은 방식이 가능했다.

foo[0]=a
# foo[1] 이 없이니 값은 null 이다.
foo[2]=b
  • Map 타입

properties 방식

spring.my-example.foo=bar
spring.my-example.hello=world

yaml 방식

spring:
  my-example:
    foo: bar
    hello: world

주의 : map key 가 자모가 아닌 또는 - 부호가 포함될때 아래와 같이 [ ] 로 감싼다.

spring:
  my-example:
    '[foo.baz]': bar

환경속성바인딩

일반유형

일반적으로 환경변수 SPRING_JPA_DATABASEPLATFORM=mysql 는 아래와 같이 변경된다.

properties 파일의 내용 spring.jpa.databaseplatform=mysql 과 동일 효과를 가진다.

List 타입 환경설정에서는 [ 와 ] 를 사용할수 없으므로 _ (어더바) 로 대체 한다.

MY_FOO_1_ = my.foo[1]
MY_FOO_1_BAR = my.foo[1].bar
MY_FOO_1_2_ = my.foo[1][2]

그리고 (언더바) 로 끝나는 부분은 _ (언더바) 는 삭제된다. 위 코드에서 1,3번 행은 아래와 같이

MY_FOO_1_ = my.foo[1]
MY_FOO_1_2_ = my.foo[1][2]
# 아래와 같이 _ 가 생략 된다.
MY_FOO_1 = my.foo[1]
MY_FOO_1_2 = my.foo[1][2]

시스템속성 바인딩

일반유형

spring.jpa.databaseplatform=mysql 를 시스템속성은 아래와 같이 설정

-Dspring.jpa.database-platform=mysql
-Dspring.jpa.databasePlatform=mysql
-Dspring.JPA.database_platform=mysql

List 유형

-Dspring.my-example.url[0]=http://example.com"
-Dspring.my-example.url[1]=http://spring.io"

혹은 , 로 분리 할수도 있다.

-Dspring.my-example.url=http://example.com,http://spring.io

속성읽기

spring.jpa.database-platform 설정 값을 읽으려면

this.environment.containsProperty("spring.jpa.database-platform")

아래 방식으로는 값을 획득할수 없다!!!

this.environment.containsProperty("spring.jpa.databasePlatform")

주의 ! @Value 방식으로 값을 불러올때도 위와 같은 문제가 있다. - 로 단어구분을 했는지 살펴보자.

새로운 바인딩 API

Spring Boot 2.0 부터 지원하는 api는 더욱 편리하게 설정값을 불러올수 있다.

예를 들어 propertes 에 com.blake.foo=bar 값이 있다고 치자.

@Data
@ConfigurationProperties(prefix = "com.blake")
public class FooProperties {

    private String foo;

}

새로운 방법을 살펴보자!

@SpringBootApplication
public class Application {

    public static void main(String[] args) {
        ApplicationContext context = SpringApplication.run(Application.class, args);

        Binder binder = Binder.get(context.getEnvironment());

        // 간단하게 설정값을 바인딩 할수 있다.
        FooProperties foo = binder.bind("com.blake", Bindable.of(FooProperties.class)).get();
        System.out.println(foo.getFoo());
    }
}

List 유형

com.blake.post[0]=Why Spring Boot
com.blake.post[1]=Why Spring Cloud

com.blake.posts[0].title=Why Spring Boot
com.blake.posts[0].content=It is perfect!
com.blake.posts[1].title=Why Spring Cloud
com.blake.posts[1].content=It is perfect too!

아래와 같이 값을 바인딩 한다.

ApplicationContext context = SpringApplication.run(Application.class, args);

Binder binder = Binder.get(context.getEnvironment());

// List 값 바인딩!
List<String> post = binder.bind("com.blake.post", Bindable.listOf(String.class)).get();
System.out.println(post);

List<PostInfo> posts = binder.bind("com.blake.posts", Bindable.listOf(PostInfo.class)).get();
System.out.println(posts);

쉽지?!

끝!

Last updated