본문 바로가기
학습/Spring

[spring] 스프링부트의 외부 설정 (개념)

by KKambi 2020. 4. 11.

스프링부트의 외부 설정

  • 외부 설정 파일 = 어플리케이션에서 사용하는 설정 값들을 정의
  • application.properties
    • 스프링 부트 실행 시 자동 로딩
    • key=value 형태로 정의
    • 어플리케이션 내에서 참조 가능
    • @Value("${key}")로 멤버 필드에 주입
//application.properties
kkambi.age=20

//ApplicationRunner
public class SpringInitRunner implements ApplicationRunner {
	
    @Value("${kkambi.name}")
    private int age;
    
    @Override
    public void run(ApplicationArguments args) throws Exception {
    	System.out.println("Age: " + age);		//Age: 20 출력
    }
}

 

프로퍼티 파일의 우선순위

다양한 방법으로 정의할 수 있어서, 우선순위가 높은 것이 오버라이딩한다.

  1. 유저 홈 디렉토리에 있는 spring-boot-dev-tools.properties
  2. (★) 테스트에 있는 @TestPropertySource
    • 테스트만을 위한 프로퍼티를 정의하는 방법
    • 이 방법을 많이 사용함
  3. @SpringBootTest 애노테이션의 properties 어트리뷰트
  4. (★) Command Line Arguments
    • (java -jar JAR파일 --foo=bar)
    • SpringApplication.setAddCommandLineProperties(false)
    • main 메소드에서 application run 이전에 설정할 수 있음
  5. SPRING_APPLICATION_JSON (환경 변수 또는 시스템 프로티) 에 들어있는 프로퍼티
  6. ServletConfig 파라미터
  7. ServletContext 파라미터
  8. java:comp/env JNDI 애트리뷰트
  9. System.getProperties() 자바 시스템 프로퍼티
  10. OS 환경 변수
  11. RandomValuePropertySource
  12. JAR 밖에 있는 특정 프로파일용 application properties
  13. JAR 안에 있는 특정 프로파일용 application properties
  14. JAR 밖에 있는 application properties
  15. JAR 안에 있는 application properties
  16. @PropertySource
  17. 기본 프로퍼티
    • 스프링부트는 기본 프로퍼티 제공
    • 자동설정 등에 의해 지정되는 많은 key:value

 

테스트에서 property에 설정된 값 가져오기

 

  • 모든 프로퍼티 -> Environment 클래스에 담김
  • getProperty("key")
@RunWith(SpringRunner.class)
@SpringBootTest
public class ApplicationTest {
	
    @Autowired
    Environment env;
    
    @Test
    public void getAge(){
    	assertThat(env.getProperty("kkambi.age")).isEqualTo("20");
    }
}

 

 

테스트 빌드와 프로퍼티 적용

  1. src/main 디렉토리 빌드 (application.properties가 담긴 resources도 포함해서!)
  2. 클래스패스에 놓음
  3. src/test 디렉토리 빌드
  4. 클래스패스에 놓음 -> application.properties 오버라이딩

cf) application.properties라는 이름이 아니어도 상관없음. 관례일 뿐!

결국엔 resource 디렉토리 내 모든 프로퍼티 적용시키기 때문에...

 

 

테스트 빌드 시 주의점

  • 프로퍼티가 오버라이딩된다.
  • 테스트 프로퍼티가 없으면, 소스의 프로퍼티를 적용한다.
  • 하지만 오버라이딩된다고 해서, main properties에는 존재하고, test properties에 존재하지 않는 value를 가져올 순 없음

 

백기선님은 프로퍼티 오버라이딩이라 말하셨지만.....

내가 내린 결론은 다음과 같다

  • 오버라이딩보단 아예 교체된다고 보는 게 이해하기 편하다
  • 오버라이딩이라면 main properties에만 존재하는 key를 참조할 수 있어야 할 것

 

Develop / Test Property Overriding 문제점을 해결하는 쉬운 방법

  • @TestPropertySource ( location = "classpath:/applicaiton.test.properties" )
  • 테스트 클래스에 선언
  • 적용시킬 프로퍼티 파일을 지정할 수 있음
  • 프로퍼티 2순위
@RunWith(SpringRunner.class)
@TestPropertySource(location="classpath:/application.test.properties")
@SpringBootTest()
public class ApplicationTest(){
	
}

 

프로퍼티 key-value를 어노테이션에서 지정하기

  • 테스트 클래스에 선언하는 @TestPropertySource / @SpringBootTest
  • @TestPropertySource(properties = "kkambi.name=test")
  • @SpringBootTest(properties = "kkambi.name=test")

 

프로퍼티에서 랜덤 값 이용하기 (RandomValuePropertySource)

  • ${random.int}
  • properties 파일 내에서 해당 값을 이용가능
  • 주의점 = 서버 포트는 0으로 해야 랜덤 (가용 포트 내에서 랜덤을 주는 의미)

 

프로퍼티 value를 재사용할 수 있음

${ } = placeholder

//application.test.properties
kkambi.name=kkambi
kkambi.fullName=${kkambi.name} Babo

 

프로퍼티 파일 오버라이딩 시 주의점

  • 다른 위치에 있는 경우, 파일 이름이 동일해도 오버라이딩되지 않음
  • 4곳에 위치 가능
  • 방법1이 제일 우선순위가 높다
    1. file:./config/
    2. file:./
    3. classpath:/config/
    4. classpath:/

cf) JAR파일을 실행하는 위치 = 루트 디렉토리 = file:./

cf) classpath = 리소스 디렉토리 = resources/

 

 

댓글