

현 프로젝트는 api, core, infrastructure 세 모듈로 구성되어있다.
IntelliJ IDEA를 사용하여 Spring Boot 모듈을 추가했을 때 기본적으로 build.gradle을 구성해준다.
그래서 프로젝트의 build.gradle과 각 모듈의 build.gradle 3개를 총합하면 4개의 build.gradle 파일이 존재하고 있다.
각 모듈에서만 사용될 의존성 등은 모듈 속 빌드 설정을 하면 되겠지만
전체 프로젝트의 빌드 설정을 어떻게 하면 효과적으로 사용할 수 있을지 고민이 되었다.
또한,
빌드 결과물이 각 모듈마다 출력된다. 이것들을 추후 배포할 때 어떤 방법을 택해야 할까.
build.gradle (:api) 예시plugins {
id 'org.springframework.boot' version '3.1.0'
id 'java'
}
bootJar {
enabled = true // Spring Boot 실행 JAR 생성
}
jar {
enabled = false // 표준 JAR 비활성화
}
dependencies {
implementation project(':core') // 내부 라이브러리 의존성
implementation 'org.springframework.boot:spring-boot-starter-web'
}
jar 태스크는 표준 Java 라이브러리 jar 파일을 생성
bootJar 태스크는 Spring Boot 실행 가능한 jar 파일을 생성
java -jarapi): bootJar ⭕, jar ❌ core, infrastructure): bootJar ❌, jar ⭕jar, bootJar 둘 다 활성화하면?build/libs/ 디렉토리에 둘 다 생성됨jar 또는 bootJar 태스크가 명시되지 않으면?jar 태스크를 실행하나,bootJar 태스크를 실행 (jar❌)멀티 모듈 프로젝트의 빌드 전략..
크게 두 가지의 선택지가 있다.
통합 단일 JAR 생성
api, core, infrastructure 병합됨모듈별 개별 JAR 생성
나는 1번을 선택 (REST API 백엔드 서버)
multi-module-project/
├── build.gradle
├── settings.gradle
├── api
│ └── build.gradle
├── core
│ └── build.gradle
├── infrastructure
| └── build.gradle
...
plugins {
id 'org.springframework.boot' version '3.1.0' apply false
id 'io.spring.dependency-management' version '1.1.0'
id 'java'
}
allprojects {
group = 'com.example'
version = '1.0.0'
repositories {
mavenCentral()
}
}
subprojects {
apply plugin: 'java'
apply plugin: 'io.spring.dependency-management'
java {
sourceCompatibility = JavaVersion.VERSION_17
targetCompatibility = JavaVersion.VERSION_17
}
}
dependencies {
implementation project(':core')
implementation project(':infrastructure')
}
bootJar {
enabled = false
}
jar {
enabled = false
}
settings.gradlerootProject.name = 'multi-module-project'
include('api', 'core', 'infrastructure')
plugins {
id 'org.springframework.boot' version '3.1.0'
id 'java'
}
dependencies {
implementation project(':core')
implementation project(':infrastructure')
implementation 'org.springframework.boot:spring-boot-starter-web'
implementation 'org.springframework.boot:spring-boot-starter-actuator'
}
bootJar {
enabled = true
}
jar {
enabled = false
}
plugins {
id 'java'
}
dependencies {
implementation 'org.springframework.boot:spring-boot-starter'
}
bootJar {
enabled = false
}
jar {
enabled = true
}
plugins {
id 'java'
}
dependencies {
implementation project(':core')
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
implementation 'org.springframework.boot:spring-boot-starter-amqp'
implementation 'org.postgresql:postgresql'
}
bootJar {
enabled = false
}
jar {
enabled = true
}
루트 빌드 설정에 다음과 같이 lombok 의존성을 추가한 상태.
subprojects는 하위 프로젝트(api, core, infrastructure)의 공통 설정subprojects {
dependencies {
compileOnly 'org.projectlombok:lombok'
annotationProcessor 'org.projectlombok:lombok'
..
}
}
build.gradle(:core) 에 다음 의존성을 추가한 상태
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-data-redis'
}
여기서 빌드를 하면 다음과 같은 로그를 볼 수 있다.

Q. 왜
core에서는 lombok과 redis 의존성을 찾을 수 없나?A. 버전을 명시해주면 더 이상 해당 오류는 등장하지 않는다.
예)compileOnly 'org.projectlombok:lombok'->compileOnly 'org.projectlombok:lombok:1.18.30'
Q. 왜 버전을 명시하지 않아도 잘 동작하기도 했었나?
A. 의존성을 자동으로 관리해주는 플러그인 & 의존성이 설정되어있었기 때문이다.
Q. 부모 POM이 무엇인가?
A. Maven 프로젝트에서 상위 프로젝트의 의존성, 플러그인 등 빌드 설정을 정의하는 POM 파일이다. 부모 POM에서 의존성, 플러그인 등을 정의하면 하위 프로젝트에서 버전을 명시하지 않아도 된다.
Q. Maven이 아닌 Gradle 설정은 어떻게 하나?
부모 POM 개념은 없지만
io.spring.dependency-management플러그인 등을 사용하여 자동 버전 관리 필요
플러그인 없이 라이브러리만 추가하는 것은 가능하지만, IDE와의 통합 및 빌드 과정에서의 편리함이 떨어질 수 있다.
Q.
apply plugin:과,plugins{...}의 차이
apply plugin:
Gradle 스크립트에서 플러그인을 적용하는 전통적인 방법
플러그인을 적용한 후, 해당 플러그인에 대한 추가 설정 필요
plugins{...}
Gradle의 새로운 DSL(도메인 특화 언어)
플러그인을 선언적으로 적용하는 방법
현대적이고 안정성이 높은 방법
플러그인의 버전을 명시적으로 지정 가능
플러그인 적용 순서와 관련된 문제를 줄일 수 있음
Gradle의 초기화 단계에서 플러그인을 적용하므로, 더 안전하고 예측 가능한 방식으로 플러그인을 사용가능