---
tags: boot, application.properties
---
application.properties 상속
===
application.properties 는 보통 /src/main/resource 하위에 작성하여 관리를 하게 된다.
> 처음 만들어주는 위치가 그렇다 보니 많이들 이 위치에 두게 된다.
> 다른 위치에 비해 우선순위도 높지 않아 나중에 더 높은 우선순위에 의해 양보해주기도 한다.
이하 application.properties 는 편의상 `a.p` 라고 하겠다.
또한 /src/main/resources 는 편의상 `main/` 이라고 하겠다.
a.p는 main/ 밑에 두었어도 이름을 달리하여 프로필 마다 참조하도록 할수 있다
그러다 보면 같은위치의 a.p가 많이 생기는데, 각각 어떻게 상호 작용 하는지 알아보자.
## 1. main/a-{profile}.p 는 main/a.p를 상속 받는다.
profile 이 있는 a-{profile}.p 는 a.p 의 값들을 상속 받는다.
main/a.p
ㄴ main/a-local.p
ㄴ main/a-test.p
> 이경우 test 프로필로 동작시키면, a.p 의 값들을 먼저 가져오고, 그 위에 a-test.p 의 값으로 override 한다.
### 테스트 준비
profile을 test 로 설정하여 a-test.p 를 참조 하도록 설정 한다.
- 1. a.p
```
temp.a1=a
temp.a2=a
```
- 2. a-test.p
```
#temp.a1=a <- 주석처리 하였다.
temp.a2=dev
```
- 3. logging
```java=
@ActiveProfiles("dev") // test 프로필로 지정
@RunWith(SpringRunner.class)
@SpringBootTest
public class ApTest {
@Value("${temp.a1}")
String a1;
@Value("${temp.a2}")
String a2;
@Test
public void 확인(){
System.out.println("a1 : " + a1); // a
System.out.println("a2 : " + a2); // dev
}
}
```
### 결과
```
a1 : a <- 주석 했는데도 a.p 것을 상속받아 출력함!
a2 : dev
```
a-test.p에서 a1을 주석 했음에도 a.p 의 것을 출력했다.
상속 되었기 때문이다.
## 2. main/a.p 와 test/a.p 의 혼용시, test/a.p가 main/a.p 를 덮어 써 버린다.
테스트시에는 main/ 경로와 test/ 경로 둘다 쓸수 있다.
특징은 test/a.p 가 더 나중에 빌드 되기 때문에, 디렉토리 구조상 같은 main/a.p 를 덮어 써 버린다.
> 즉 main/a.p 를 썼더라도, test/a.p 의 것만 쓸수 있게된다.
> 이름이 같기 때문이다.
### 테스트 준비
2개의 경로에 각각 a.p 를 준비한다.
- 1. main/a.p
```
temp.a1=a
temp.a2=a
```
- 2. test/a.p
```
#temp.a1=a <- 주석처리 하였다.
temp.a2=b
```
- 3. logging
```
`1. main/a-{profile}.p 는 main/a.p를 상속 받는다.` 와 같아서 생략
```
### 결과
```
a1 : ${temp.a1} <- 상속되지 않아 값을 출력하지 못한다.
a2 : b
```
위 결과의 이유는, 다시한번 얘기 하지만 동작원리가 다음과 같기 때문 이다.
1. 빌드시점에서 main/a.p 이 생성 되고,
2. 테스트시점에서 test/a.p 가 생성 되면서, main/a.p 를 덮어 써 버리기 때문이다.
> 아마도 Junit 은 product 코드와 확실하게 분리 하는것이 목적인것에 기인 한것으로 보인다.
물론 dev용 프로퍼티 test/a-dev.p 를 별도로 만들고, dev 프로파일로 실행 시키면, 파일 이름이 달라 덮어 쓰지 않는다.
이 정보를 바탕으로 퀴즈를 한번 풀어보자.
## 퀴즈
main/ 경로와 test/ 경로에 다음과 같이 3개의 파일이 존재 한다고 가정 하자.
main/a.p
test/a.p
ㄴ test/a-dev.p
각각의 프로퍼티 구성은 다음과 같다.
- 1. main/a.p
```
temp.a1=a
temp.a2=a
```
- 2. test/a.p
```
temp.a1=test
temp.a2=test
```
- 3. test/a-dev.p
```
temp.a1=test-dev
```
이때 dev 프로필로 테스트 환경에서 로깅을 해보면 a1과 a2는 어떻게 출력 될까?
### 정답
```
a1 : test-dev
a2 : test
```
### 해설
1. main/a.p 가 빌드 되면서 클래스 패스에 생성된다.
2. 곧바로 test/a.p 가 빌드 되면서 클래스 패스에 생성되면서 동일한 이름으로 생성되었던 main/a.p 가 덮어씌여지며 사라지게 된다.
3. test/a.p 에 있던 a1=test, a2=test 를 test/a-dev.p 가 상속받게 되는데, a1 test/a-dev.p 가 재작성 하여 test-dev 를 출력지만, a2는 작성한것 이 없어 부모인 test/a.p 의 a2 값을 출력했기 때문이다.
### 테스트용 application.properties 의 적절한 위치?
테스트용 application.properties 는 src/test/resources 하위에 만들어도 좋다. 대신 src/main/resources 에 있는 파일과 이름을 겹치게 만들지 않는것이 좋다. 통합테스트시에는