Spring Boot로 제작한 Application을 다른 Application에서 가져다 사용해보자.
Spring Boot를 기반으로 제작한 Application을 다른 Application에서 가져다 사용하는 방법에 대해 알아보고, 문제가 될 수 있는 부분을 찾아본다.
1. 개요
- Spring boot 를 기반으로 한 Demo1 제작
- Demo1에서 application.yml에 값(value)을 입력
- Demo1을 실행하여 application.yml의 값의 출력을 확인.
- Demo1 packaging
- Demo1의 jar 내부에 application.yml이 존재함을 확인.
- Demo1에 대한 의존성을 가지고있는 Demo2를 작성
- Demo2에서 Demo1의 application.yml 값을 가져와지는지 확인.
2. Demo1
Spring Boot 를 기반으로 한 Demo1을 제작합니다.
2.1. 폴더구성
- 실행을 위한
Demo1Application.java가 존재 - application.yml의 값을 가져오기 위한
Demo1Tester.java가 위치
2.2. pom.xml
1 |
|
lombok 이외에는 특별한거 하나 없는 intellij 기본 생성 Spring Boot Application이다.
2.3. application.yml
test.example.value 의 값으로 demo1을 세팅한다.
1 | test: |
2.4. Demo1Tester.java
application.yml의 값을 가져오기 위한 Class
Autowired 테스트를 위해@Component로 선언한다.
1 | import lombok.Data; |
2.5. Demo1Application.java
Demo1Tester를 autowired 한 뒤 value 의 값을 가져와 log로 출력한다.
1 | import com.example.demo1.logic.Demo1Tester; |
2.6. Demo1 실행결과
1 | . ____ _ __ _ _ |
demo1이 출력되는 것을 확인할 수 있다.
2.7. Demo1 packaging
Spring Boot의 repackage를 스킵하도록 한다.
1 | > mvn clean install -DskipTests -Dspring-boot.repackage.skip=true |
2.8. Demo1.jar
application.yml 이 포함되었음을 확인할 수 있다.
3. Demo2
Demo1에 의존성을 가지고 있는 Demo2를 생성한다.
3.1. 폴더구성
- 실행을 위한
Demo2Application.java가 존재 - 여러가지 케이스 테스트를 위한 application.yml 존재
3.2. pom.xml
demo1 의 라이브러리를 dependency에 추가한다.
1 |
|
3.3. Demo2Application.java
@ComponentScan으로 demo1의 @Component를 탐색한다.Demo1TesterClass를 Autowired 한다.
value 값을 출력한다.
1 | import com.example.demo1.logic.Demo1Tester; |
4. 결과
4.1. 시나리오1
기본실행
- Demo2 application.yml 삭제 (null)
- Demo2Application 실행
1 | 2020-01-04 00:10:06.508 INFO 2968 --- [ main] com.example.demo2.Demo2Application : Starting Demo2Application on park-PC with PID 2968 (started by park in D:\Dropbox\프리랜서\2020\demo2) |
demo1과 demo2의 값이 demo1로 출력되는 것을 확인.
demo1 : tester.getValue은 demo2에 포함되는 코드가 아님에도 출력됐음을 확인.
4.2. 시나리오2
- Demo2에 application.yml 추가 (empty)
- Demo2Application 실행
1 | 2020-01-04 00:16:29.628 INFO 14512 --- [ main] com.example.demo2.Demo2Application : Starting Demo2Application on park-PC with PID 14512 (started by park in D:\Dropbox\프리랜서\2020\demo2) |
test.example.value값이 존재하지 않아 Spring boot 실행 시 에러 발생
4.3. 시나리오3
- Demo2에 application.yml에 값 추가
- Demo2Application 실행
demo2/application.yml
1 | test: |
결과
1 | 2020-01-04 00:18:22.742 INFO 19544 --- [ main] com.example.demo2.Demo2Application : Starting Demo2Application on park-PC with PID 19544 (started by park in D:\Dropbox\프리랜서\2020\demo2) |
demo1과 demo2의 값이 demo2로 출력되는 것을 확인.
demo1 : tester.getValue은 demo2에 포함되는 코드가 아님에도 출력됐음을 확인.
4.4. 결론
- jar 내부 application.yml 은
@ComponentScan시 값이 읽힐 수 있다.- 다만 jar를 import 하는 application의 application.yml이 아예 존재하지 않아야 한다.
- 실행되는 application에 application.yml 설정파일이 존재한다면 jar내부의 application.yml은 무시된다.
- 실행되는 application의 application.yml 내부 값이 적용된다.
5. 추가
- @ComponentScan 시 basePackages 설정에 대한 고민
위의 테스트에서 자꾸 demo2에 포함되지 않는 demo1의 코드가 실행되는 것을 알 수 있다. 이는 @ComponentScan의 basePackages에 com.example.demo1 로 설정되어있기 때문이다. (원하지 않는 Demo1Application이 실행될 수 있다는 이야기다.)
따라서 다른 Application의 Component를 사용할 경우에는 최소한의 범위로 선언해서 사용할 수 있도록 해야한다.
@ComponentScan(basePackages = {"com.example.demo2", "com.example.demo1.logic"})
1 | 2020-01-04 00:23:49.949 INFO 10644 --- [ main] com.example.demo2.Demo2Application : Starting Demo2Application on park-PC with PID 10644 (started by park in D:\Dropbox\프리랜서\2020\demo2) |
com.example.demo1.logic으로 선언했을 경우Demo1Application이 실행되지 않는것을 확인할 수 있다.