Spring/boot

[spring-boot] 외부설정(application.properties)

jay Joon 2021. 1. 13. 22:26

spring-boot-study

[ Inflearn ] 스프링 부트 개념과 활용 강의를 듣고 챕터별 간단하게 정리합니다.

내용적 오류가 존재할 수 있으며 부족한 부분은 언제든지 지적해주시면 감사드립니다.


외부 설정(application.properties)

 

이번 챕터에서는 application.properties의 우선순위와 사용방법을 알아볼 것이다.

 

 

프로퍼티(properties)의 정의는 단순한 Key와 Value로 형태로 제공하는 Data이다.

 

 

프로퍼티 우선순위

  1. spring-boot-devtools를 활성화시켰을 때 $HOME/. config/spring-boot 안에서 제공하는 프로퍼티
  2. 테스트에 사용한 @TestPropertySource가 제공하는 프로퍼티
  3. @SpringBootTest 또는 슬라이스 테스트용 애노테이션의 properties 속성으로 제공하는 프로퍼티
  4. 커맨드 라인 아규먼트
  5. SPRING_APPLICATION_JSON 환경 변수 또는 시스템 프로퍼티에 인라인 JSON으로 정의되어 있는 프로퍼티
  6. ServletConfig 초기 매개변수
  7. ServletContext 초기 매개변수
  8. java:comp/env에 들어있는 JNDI 애트리뷰트
  9. 자바 시스템 프로퍼티 (System.getProperties())
  10. 운영체제 환경 변수
  11. RandomValuePropertySource. random 접두어를 가지고 있는 프로퍼티, random.* 에 무작위 값을 제공하는 프로퍼티 소스.
  12. JAR 패키지 외부에 있는 특정 프로파일용 애플리케이션 프로퍼티. (application-{profile}. properties 또는 YAML
  13. JAR 패키지 내부에 있는 특정 프로파일용 애플리케이션 프로퍼티. (application-{profile}.properties 또는 YAML
  14. JAR 패키지 외부에 있는 애플리케이션 프로퍼티. (application.properteis 또는 YAML)
  15. JAR 패키지 내부에 있는 애플리케이션 프로퍼티. (application.properteis 또는 YAML)
  16. @Configuration 클래스에 사용한 @PropertySource로 읽어 들인 프로퍼티
  17. SpringApplication.setDefaultProperties()로 설정할 수 있는 기본 프로퍼티

(출처 : https://www.whiteship.me/spring-boot-external-config/)

 

 

자 그럼 다음과 같이 spring-boot 프로젝트를 생성했을 때 resources 밑에 있는 apllication.properites의 우선순위는 몇 위 인가?

image

JAR 패키지 내부에 있는 애플리케이션 프로퍼티. (application.properteis 또는 YAML) 임으로 15위가 된다.

 

 

사용방법

자 그러면 application.properties 안에 키(key)와 값(value)을 등록하고 또 사용해보자.

test.projectName = testProject
test.version = ${random.int}
test.projectNameAndVersion=${test.projectName} ${test.version}

application.properties 에 다음과 같이 작성해보자.

${random.~~}을 통하여 Random 한 인수 값을 Setting 할 수 있고

Property Placeholders를 이용하여 미리 정의된 Value 값들을 이용할 수 도 있다.

 

 

간단한 외부 설정이 끝났으니 외부 설정을 사용해보자.

@Value("${test.projectName}")
String projectName;

@Value("${test.version}")
int version;

@Value("${test.projectNameAndVersion}")
String projectNameAndVersion;

다음과 같이 @Value 애노테이션을 이용하여 외부 프로퍼티에 작성되어 있는 값을 참조하여 해당 변수에 할당할 수 있다.

 

 

 

Test 코드를 작성하면서 발생할 수 있는 상황을 알아보자

만약 Test 코드를 작성한다고 하였을 때 실제 서비스에 있는 application.properties의 외부 설정을 사용하고 싶지 않고

Test 만의 application.properties을 따로 두고 싶을 땐 어떻게 해야 할까?

@SpringBootTest
class DemoApplicationTests {

    @Autowired
    Environment environment;
    @Test
    void propertiesTest() {
        Assertions.assertThat(environment.getProperty("test.projectName")).isEqualTo("testCodeProject");
    }

}

이 코드처럼 이제 test.projectName(key) 값이 testCodeProject(value) 값을 가지고 싶다.

 

하지만 classPath:/ 밑에 있는 application.properties의 파일은 지금 하나이다. 따라서 위에 있는 Test는 실패할 것이다.

 

따라서 Test classPath:/ 아래에 똑같이 application.properties를 정의하여 사용해보자.

image

 

다음 application.properties 에 test.projectName(key) 에 대한 value 값을 재 정의해보자.

test.projectName = testCodeProject

 

그다음 Test를 실행하면?

image

오류가 발생할 것이다.

왜냐하면 test 밑에 있는 application.properties 가 원래 존재하고 있는 application.properties를 오버 라이딩하기 때문에

@Value("${test.version}")
int version;

이 코드에서 test.version을 값을 찾을 수 없기 때문이다.

 

이러한 문제점을 해결하기 위해선 test 밑에 있는 applcation.properties 랑 기존 사용하고 있는 application.properties의 프로퍼티 값을 일치해주면 되는데.

매우 귀찮다.

 

 

우리는 test.projectName의 값만 변경하고 싶은데 나머지 프로퍼티 값도 작성하는 것은 비효율 적이다.

 

  1. @TestPropertySource(properties = "")를 이용하는 방법 배열로 여러 가지의 프로퍼티 값을 재정의 할 수 있습니다.

test 밑에 있는 application.properties을 삭제하고 @TestPropertySource 이용하여 해결할 수 있다.

 

 

  1. @TestPropertySource(locations = "") 배열로 여러 개의 프로퍼티 값을 바꾸기 힘들 때 파일을 이용하여 재정의 할 수 도 있다.

image