# 24. 외부화된 구성 by ys

스프링 부트는 환경 설정을 외부에 할 수있게 해서 같은 어플리케이션 코드를 다른 환경에서 사용할 수있게 한다. 외부 환경 설정을 하기 위해 Properties 파일들, YAML 파일들, 환경변수들 그리고 Command-Line 인수들을 사용할 수 있다. 설정된 프라퍼티들은 `@Value`를 사용해 직접 빈들에 주입할 수도 있고, 스프링의 `Environment` 추상을 통해 접근하거나 `@ConfigurationProperties`를 통해 [구조화된 객체에 묶일 수도 있다.](https://kgmyh.github.io/blog/2017/12/10/spring-boot-chapter04/#heading-247-Type-safe-%EC%84%A4%EC%A0%95-%ED%94%84%EB%9D%BC%ED%8D%BC%ED%8B%B0%EB%93%A4)

스프링 부트는 값들을 합리적으로 재정의하도록 설계한 매우 특별한 `PropertySource` 순서를 사용한다. 프라퍼티들은 다음 순서대로 적용된다.

1. 홈 디렉토리상의 [Devtools의 전역설정 프라퍼티](https://kgmyh.github.io/blog/2017/12/04/spring-boot-chapter03/#heading-204-%EC%A0%84%EC%97%AD%EC%84%A4%EC%A0%95%EB%93%A4)(devtools가 실행 중일때 `~/.spring-boot-devtools.properties`)
2. 테스트 할 때 `@TestPropertySource` 어노테이션
3. 테스트 할 때 `@SpringBootTest#properties` 어노테이션
4. Command-Line 인수
5. `SPRING_APPLICATION_JSON`에 설정된 프라퍼티들(환경변수나 시스템 프라퍼티 내장된 inline JSON)
6. `ServletConfig` 초기파라미터
7. `ServletContext` 초기파라미터
8. `java:comp/env`로 부터의 JNDI 속성
9. Java 시스템 프라퍼티(`System.getProperties()`).
10. 운영체제 환경변수
11. `random.*` 형태의 프라퍼티들만 가지고 있는 `RandomValuePropertySource`
12. 패키지된 jar 파일 외부의 [프로파일 관련 어플리케이션 프라퍼티들](https://kgmyh.github.io/blog/2017/12/10/spring-boot-chapter04/#heading-244-%ED%94%84%EB%A1%9C%ED%8C%8C%EC%9D%BC-%EA%B4%80%EB%A0%A8-%ED%94%84%EB%9D%BC%ED%8D%BC%ED%8B%B0%EB%93%A4)(`application-{profile}.properties`와 YAML 문서)
13. 패키지된 jar 파일 내부의 [프로파일 관련 어플리케이션 프라퍼티들](https://kgmyh.github.io/blog/2017/12/10/spring-boot-chapter04/#heading-244-%ED%94%84%EB%A1%9C%ED%8C%8C%EC%9D%BC-%EA%B4%80%EB%A0%A8-%ED%94%84%EB%9D%BC%ED%8D%BC%ED%8B%B0%EB%93%A4)(`application-{profile}.properties`와 YAML 문서)
14. 패키지된 jar 파일 외부의 어플리케이션 프라퍼티들 (`application.properties`와 YAML 문서)
15. 패키지된 jar 파일 내부의 어플리케이션 프라퍼티들 (`application.properties`와 YAML 문서)
16. `@Configuration`클래스에 선언한 `@PropertySource` 어노테이션
17. 기본 프라퍼티들 (`SpringApplication.setDefaultProperties`를 사용해 작성된)

구체적인 예제를 제공하기 위해, `name` 프라퍼티를 사용하는 `@Component`를 다음 예제와 같이 개발하고 있다고 가정한다.

```java
import org.springframework.stereotype.*;
import org.springframework.beans.factory.annotation.*;

@Component
public class MyBean {

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

    // ...
}
```

어플리케이션의 클래스패스(jar파일 내)상에 `application.properties` 파일이`name`에 대한 유용한 기본 프라퍼티 값을 제공할 수있다. 새로운 환경에서 실행될 때, `name`을 재정의한 `application.properties` 파일이 jar파일 외부에서 제공될 수도 있다. 일회성 테스트를 위해 시작할 때 Command-Line 인수를 이용해 전달 할 수 있다. (예를 들어 `java -jar app.jar --name="Spring"`).

>

| ![\[팁\]](https://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/images/tip.png)                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 |
| ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| <p><code>SPRING\_APPLICATION\_JSON</code> 프라퍼티는 환경변수로 Command line상에서 제공될 수 있다. 예를 들어 다음 라인을 UNI\*X 쉘에서 사용할 수있다.<br><strong>$ SPRING\_APPLICATION\_JSON='{"acme":{"name":"test"}}' java -jar myapp.jar</strong><br>위 예가 실행되면, 스프링 <code>Environment</code>에서는 <code>acme.name=test</code>로 된다. JSON을 시스템 프라퍼티에서 <code>spring.application.json</code>을 사용해 다음 예처럼 제공할 수도 있다.<br><strong>$ java -Dspring.application.json='{"name":"test"}' -jar myapp.jar</strong><br>JSON을 Command-line 인수를 사용해 다음 예 처럼 제공할 수도 있다.<br><strong>$ java -jar myapp.jar –spring.application.json='{"name":"test"}'</strong><br>다음과 같이 JNDI 변수를 이용해 JSON을 제공을 할 수도 있다. <br><strong><code>java:comp/env/spring.application.json</code></strong></p> |
