build.gradle
초기 설정
처음 프로젝트를 생성했을때 단일 모듈로 main모듈과 build.gradle이 생성되어있습니다.
우리는 멀티 모듈로 구성해야하기 때문에 이 모듈과 build.gradle을 분리해줄 겁니다.
생성해줄 모듈은 외부요청을 받아올 역할을 수행할 api모듈과 도메인 모델을 정의할 domain모듈을 생성해줄 것입니다.
먼저 루트 build.gradle입니다.
기존 설정과 다른 점이 있습니다.
크게 allprojects와 subprojects가 새로 생긴것을 확인할 수 있습니다.
allprojects
루트 모듈뿐만 아니라 프로젝트에 포함된 모든 모듈의 build.gradle에 영향을 미치는 설정입니다.
subprojects
루트 모듈을 제외한 하위 모듈의 build.gradle에 영향을 미치는 설정입니다.
subprojects에는 공통적으로 사용해줄 의존성인 lombok의존성을 선언해주었습니다.
그리고 settings.gradle에서 하위 모듈을 설정해주기 위해 include '[하위 모듈 이름]' 으로 설정해줍니다.
다음은 api 모듈입니다.
api모듈에는 다른 설정을 제외하고 의존성 설정만 존재합니다.
외부에서 통신을 필요로 하기 때문에 springboot에서 제공해주는 starter팩을 가지고 있습니다.
분명 api모듈의 gradle.build에는 starter팩 의존성만 받았는데 롬복을 가지고 있습니다.
바로 루트 모듈에서 루트 모듈의 하위 모듈인 api모듈도 공통으로 사용할 롬북을 선언해주었기 때문입니다.
그리고 처음보는 메소드가 있습니다.
implementation project('모듈 이름')
project 메소드는 allprojects, subprojects와 다르게 해당 모듈의 build.gradle에만 추가됩니다.
이는 해당 프로젝트에서 의존하려는 다른 프로젝트를 독립적으로 설정해주게 됩니다.
(1.4)그림을 보시면 하위 의존성으로 domain 모듈이 존재하는 것을 확인할 수 있습니다.
모듈간 의존 방법 (implementation vs api)
implementation
Gradle이 컴파일 클래스 경로에 종속 항목을 추가하고 빌드 출력에 종속 항목을 패키징합니다. 그러나 모듈에서
implementation
종속 항목을 구성하면 모듈이 컴파일 시간에 종속 항목을 다른 모듈에 누출하기를 바라지 않는다는 것을 Gradle에 알려주는 것입니다. 즉 종속 항목은 런타임에만 다른 모듈에서 이용할 수 있습니다.
api 또는 compile(지원 중단됨) 대신 이 종속 항목 구성을 사용하면 빌드 시스템에서 다시 컴파일해야 하는 모듈 수가 줄어들기 때문에 빌드 시간이 크게 개선될 수 있습니다. 예를 들어 implementation 종속 항목이 API를 변경하면 Gradle은 이 종속 항목과 이에 직접적으로 종속된 모듈만 다시 컴파일합니다. 대부분의 앱과 테스트 모듈은 이 구성을 사용해야 합니다.
api
Gradle은 컴파일 클래스 경로와 빌드 출력에 종속 항목을 추가합니다. 모듈에 api 종속 항목이 포함되면 모듈이 다른 모듈로 종속 항목을 이전하여 다른 모듈에서 런타임과 컴파일 시간에 사용할 수 있도록 한다는 것을 Gradle에 알려주는 것입니다.이 구성은 compile(현재는 지원 중단됨)처럼 작동하지만 주의해서 다른 업스트림 소비자에게 이전해야 하는 종속 항목과만 사용해야 합니다. 그 이유는 api 종속 항목이 외부 API를 변경하면 Gradle이 컴파일 시 종속 항목에 액세스 권한이 있는 모든 모듈을 다시 컴파일하기 때문입니다. 따라서 api 종속 항목 수가 많으면 빌드 시간이 크게 증가할 수 있습니다. 종속 항목의 API를 별도의 모듈에 노출하지 않으려면 라이브러리 모듈에서 implementation 종속 항목을 대신 사용해야 합니다.
즉, implementation은 종속성이 변경되면 해당 모듈과 직접 연결된 모듈만 재빌드됩니다.
그리고 api는 종속성이 변경되면 해당 모듈에 엑세스 권한이 있는 모든 모듈이 재빌드됩니다.
//B dependencies{ api projects(':A') } //C dependencies{ implementation projects(':B') }
B모듈은 A모듈에 의존하고 있고 C모듈은 B모듈에 의존하고 있습니다. 그리고 B모듈은 api를 통해 종속하고 있고 C모듈은 implementation을 통해 종속하고 있습니다.
A <- B (api로 의존) <- C 으로 나타낼 수 있습니다.
api 종속을 통해 C는 A에 직접 종속하지는 않지만 접근이 가능합니다.
그렇기 때문에 A가 변경되면 B,C가 모두 재빌드됩니다.
A <- B (implementation으로 의존) <- C로 나타낸다면
implementation 종속을 통해 A모듈에 직접 접근이 가능한 모듈은 B이기 때문에 C에서는 접근이 불가능합니다.
그렇기 때문에 A가 변경되면 B까지만 재빌드되는것입니다.
다음은 domain 모듈 입니다.
domain 작업에 필요한 의존성만 설정되어있는 것을 확인할 수 있습니다. (jpa, h2, mysql ...)
build.gradle에서 설정해준 의존성 뿐만 아니라 루트 모듈에서 설정해준 롬북도 함께 존재하는 것을 확인할 수 있습니다.
여기서 확인해 봐야할 것은 bootJar와 jar입니다.
jar
jar는 Java Archieve로 java코드를 실행할 수 있는 형태로 압축한 파일입니다.
클래스파일, 리소스, 의존 파일등을 포함하고 있습니다.
bootJar
bootJar는 실행가능한 jar를 빌드하는 것으로 SpringBoot에서 제공합니다.
bootJar를 통해 소스코드를 빌드하여 jar파일을 생성해줍니다.
소스코드를 빌드하면 -plain.jar와 .jar 파일이 두개 생성되는 경우가 있습니다.
-plain.jar는 애플리케이션 실행에 필요한 의존성을 포함하지 않고 소스코드의 클래스 파일과 리소스 파일만 포함한 파일입니다.
그렇기 때문에 plain.jar파일은 실행이 되지 않습니다.
.jar는 애플리케이션 실행에 필요한 의존성을 모두 포함하고 있기 때문에 실행이 가능한 파일입니다.
그렇다면 domain모듈에는 왜 booJar=false, jar=true 설정이 있는걸까요?
domain모듈은 도메인 모듈과 데이터베이스와 관련된 모듈입니다. 그렇기 때문에 직접적으로 애플리케이션이 동작되어 배포될 필요가 없습니다.
하지만 실행되어야할 api모듈에서는 배포가 되어야합니다. 그리고 domain모듈의 jar파일이 필요합니다.
그렇기 때문에 bootJar를 통해 실행파일은 필요없지만 jar파일은 필요하기 때문에 이러한 설정이 필요한 것입니다.
그리고 실행 가능한 jar파일이 되기 위해서는 Main클래스가 필요합니다. 하지만 domain모듈은 실행 모듈이 아니기 때문에 Main클래스가 없습니다.
실행
api모듈이 domain모듈을 의존하고 있고 독립되어진 멀티모듈을 구성하여 성공적으로 데이터를 받아오는것을 확인할 수 있습니다.
참조
https://devlog-wjdrbs96.tistory.com/435
[Spring] 멀티 모듈에서 모듈별 yml 파일 관리하는 법
Multi module에서 yml 파일 관리하는 법 이번 글에서는 Multi-Module을 사용할 때 모듈 별 yml 파일 관리하는 법에 대해서 정리해보려 합니다. api 모듈 application.yml domain 모듈 application.yml 만약에 위와 같이
devlog-wjdrbs96.tistory.com
https://jongmin92.github.io/2019/05/09/Gradle/gradle-api-vs-implementation/
(Gradle dependency) api와 implementation 차이
build script의 dependencies 블록에 여러 가지 다양한 종속성 구성(api, implementation, compileOnly, runtimeOnly, annotationProcessor)을 사용하여 라이브러리 종속성을 선언할 수 있습니다. 다양한 종속성 구성 중 api
jongmin92.github.io
Gradle Implementation vs API configuration
I'm trying to figure out what is the difference between api and implementation configuration while building my dependencies. In the documentation, it says that implementation has better build time,...
stackoverflow.com
https://velog.io/@_koiil/SpringBoot-Multi-Module-with.-Gradle
SpringBoot 멀티 모듈로 변경하기
멀티 프로젝트에서 멀티 모듈로 전환!
velog.io
https://earth-95.tistory.com/132
[SpringBoot 2.5↑] 빌드 시 2가지 jar가 생성되는 현상 (executable jar & plain jar)
들어가기 전에 기존에 쓰던 springboot 2.4.11 버전을 빌드할 때에는 문제가 없었지만, springboot 2.5 버전 이후를 사용하니 빌드 시 jar가 2개 생겨 github action을 통해 진행하는 CD 프로세스가 제대로 작동
earth-95.tistory.com
'프로젝트' 카테고리의 다른 글
[ERROR] Can't commit changes from multiple changelists at once (0) | 2023.03.19 |
---|---|
[ERROR] Caused by: java.nio.file.FileSystemNotFoundException: null (0) | 2023.03.07 |
[ERROR] Cannot construct instance of ~ Cannot deserialize from Object value 에러 (0) | 2023.03.02 |
[SpringSecurity] h2 설정 (0) | 2023.02.27 |
[SpringSecurity] SpringSecurity 환경설정 (0) | 2023.02.27 |