2026. 3. 24. 17:43ㆍgradle
Multi-Module 프로젝트 Root 디렉토리의 build.gradle 샘플 전체 코드
plugins {
id 'org.springframework.boot' version '3.5.12' apply false
id 'io.spring.dependency-management' version '1.1.7' apply false
}
group = 'com.intheeast'
version = '0.0.1-SNAPSHOT'
subprojects {
apply plugin: 'java'
apply plugin: 'org.springframework.boot'
apply plugin: 'io.spring.dependency-management'
repositories {
mavenCentral()
}
java {
toolchain {
languageVersion = JavaLanguageVersion.of(17)
}
}
configurations {
compileOnly {
extendsFrom annotationProcessor
}
}
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-web'
compileOnly 'org.projectlombok:lombok'
developmentOnly 'org.springframework.boot:spring-boot-devtools'
annotationProcessor 'org.projectlombok:lombok'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
testRuntimeOnly 'org.junit.platform:junit-platform-launcher'
}
tasks.named('test') {
useJUnitPlatform()
}
}
1. 이 스크립트의 정체부터 먼저 이해해야 합니다 🧩
이 파일은 루트 프로젝트의 build.gradle 입니다.
즉, 이 파일은 하위 모듈 하나하나의 빌드 파일이라기보다,
멀티 모듈 전체의 공통 빌드 정책을 정의하는 중앙 통제 파일입니다.
예를 들어 프로젝트 구조가 다음과 같다고 해봅시다.
multi-module-demo/
├─ build.gradle // 지금 설명하는 루트 build.gradle
├─ settings.gradle
├─ module-api/
│ └─ build.gradle
├─ module-common/
│ └─ build.gradle
└─ module-user/
└─ build.gradle
이 경우 루트 build.gradle은 보통 이런 역할을 합니다.
- 하위 모듈 공통 플러그인 적용
- 공통 저장소 설정
- 공통 Java 버전 설정
- 공통 라이브러리 설정
- 공통 테스트 설정
- 공통 그룹/버전 설정
즉, “중복 제거 + 표준화” 가 핵심 목적입니다.
2. plugins 블록 설명 🔧
plugins {
id 'org.springframework.boot' version '3.5.12' apply false
id 'io.spring.dependency-management' version '1.1.7' apply false
}
이 부분은 멀티 모듈 Gradle에서 매우 중요합니다.
2-1. plugins {} 는 무엇인가?
plugins {} 블록은
이 프로젝트에서 사용할 Gradle 플러그인을 선언하는 곳입니다.
Gradle 플러그인은 쉽게 말해서:
- Java 프로젝트로 빌드하게 해주는 기능
- Spring Boot 애플리케이션으로 패키징하게 해주는 기능
- 의존성 버전을 자동 정렬해주는 기능
같은 것을 추가하는 확장 모듈입니다.
즉, 플러그인은 Gradle의 능력을 확장하는 부품입니다.
2-2. org.springframework.boot
id 'org.springframework.boot' version '3.5.12' apply false
이 플러그인은 Spring Boot 프로젝트를 Gradle에서 쉽게 다루도록 도와줍니다.
이 플러그인이 적용되면 대표적으로 다음이 가능해집니다.
bootJar태스크 생성- 실행 가능한 fat jar 생성
- Spring Boot 실행 환경에 맞는 패키징
- 기본 의존성 버전과 잘 연동됨
bootRun같은 실행 태스크 제공
즉, 일반 java 프로젝트를 Spring Boot 실행 프로젝트처럼 빌드할 수 있게 만듭니다.
2-3. io.spring.dependency-management
id 'io.spring.dependency-management' version '1.1.7' apply false
이 플러그인은 의존성 버전 관리를 쉽게 해주는 플러그인입니다.
Spring Boot는 내부적으로 수많은 라이브러리 버전 조합을 검증해서 BOM(Bill of Materials) 형태로 제공합니다.
예를 들어:
- Spring Framework
- Jackson
- Tomcat
- Logback
- JUnit
- Hibernate
이런 라이브러리들의 버전을 서로 맞춰둡니다.
이 플러그인이 있으면, 우리가 개별 라이브러리 버전을 일일이 다 적지 않아도
Spring Boot가 권장하는 버전 조합을 기준으로 관리하기 쉬워집니다.
즉, 버전 충돌과 수동 관리 부담을 줄여주는 역할입니다.
2-4. apply false가 진짜 핵심입니다 💡
apply false
이건 아주 중요합니다.
이 의미는:
"이 플러그인을 지금 루트 프로젝트에 즉시 적용하지는 않지만,
하위 프로젝트에서 사용할 수 있도록 플러그인 버전 정보는 등록해둘게"
라는 뜻입니다.
즉:
- 버전 선언은 루트에서
- 실제 적용은 하위 모듈에서
이런 전략입니다.
왜 apply false를 쓰는가?
멀티 모듈에서는 보통 하위 모듈이 여러 개입니다.
예를 들어 module-api, module-user, module-order 등 여러 모듈이 있다면,
각 모듈마다 매번 아래처럼 쓰는 것은 비효율적입니다.
plugins {
id 'org.springframework.boot' version '3.5.12'
id 'io.spring.dependency-management' version '1.1.7'
}
모든 모듈마다 중복이고, 나중에 버전 바꾸기도 귀찮습니다.
그래서 루트에서 이렇게 미리 선언해 둡니다.
plugins {
id 'org.springframework.boot' version '3.5.12' apply false
id 'io.spring.dependency-management' version '1.1.7' apply false
}
그 다음 하위 모듈에선 버전 없이 적용할 수 있게 만드는 구조입니다.
2-5. 루트에는 왜 적용하지 않는가?
루트 프로젝트는 보통 실행 가능한 애플리케이션이 아닙니다.
즉, 루트는:
main()클래스 없음- 컨트롤러 없음
- 실행용 JAR 만들 필요 없음
- 전체 모듈을 관리하는 조정자 역할
인 경우가 많습니다.
따라서 루트에 Spring Boot 플러그인을 실제로 적용하면 불필요하거나 오히려 혼란을 줄 수 있습니다.
그래서 버전만 선언하고, 실제 적용은 하위 모듈에 맡기는 것입니다.
3. group, version 설명 📦
group = 'com.intheeast'
version = '0.0.1-SNAPSHOT'
이 두 값은 Maven/Gradle 생태계에서 매우 기본적인 프로젝트 식별자입니다.
3-1. group
group = 'com.intheeast'
group은 보통 조직이나 회사, 혹은 프로젝트의 네임스페이스 역할을 합니다.
Java 패키지 네이밍처럼 거꾸로 된 도메인 구조를 많이 씁니다.
예:
com.companyorg.exampleio.myteam
이 값은 나중에 아티팩트 식별 시 사용됩니다.
예를 들어 module-api라는 모듈이 있다면 내부적으로는 이런 식의 좌표가 됩니다.
com.intheeast:module-api:0.0.1-SNAPSHOT
3-2. version
version = '0.0.1-SNAPSHOT'
프로젝트 버전입니다.
SNAPSHOT은 보통 개발 중인 아직 확정되지 않은 버전을 의미합니다.
즉:
0.0.1-SNAPSHOT→ 아직 계속 바뀔 수 있는 개발 버전0.0.1→ 릴리즈 버전 느낌
입니다.
멀티 모듈에서 루트에 group, version을 두면 하위 모듈도 이를 기본적으로 상속받습니다.
즉, 하위 모듈마다 따로 버전을 적지 않아도 됩니다.
4. subprojects {} 블록 설명 🏗️
subprojects {
...
}
이 블록은 멀티 모듈의 핵심입니다.
이 뜻은:
"루트 프로젝트 자신 말고, 모든 하위 프로젝트(subproject)들에게
이 설정들을 공통으로 적용하겠다"
라는 의미입니다.
예를 들어 settings.gradle에 다음이 있다면:
rootProject.name = 'multi-module-demo'
include 'module-api'
include 'module-common'
include 'module-user'
subprojects {} 안의 설정은 다음 모든 모듈에 적용됩니다.
:module-api:module-common:module-user
즉, 코드 한 번으로 모든 모듈의 공통 빌드 정책을 통일할 수 있습니다.
5. apply plugin 설명 ⚙️
apply plugin: 'java'
apply plugin: 'org.springframework.boot'
apply plugin: 'io.spring.dependency-management'
이제 루트에서 선언해둔 플러그인들을 실제 하위 모듈에 적용합니다.
5-1. java 플러그인
apply plugin: 'java'
이 플러그인은 해당 하위 모듈을 자바 프로젝트로 만들어줍니다.
적용되면 대표적으로 다음이 생깁니다.
src/main/javasrc/test/javacompileJavatestjar
같은 자바 프로젝트 표준 구조와 태스크가 활성화됩니다.
즉, 이 플러그인이 있어야 Gradle이
“아, 이건 자바 소스를 컴파일하는 프로젝트구나”
라고 이해합니다.
5-2. org.springframework.boot 플러그인
apply plugin: 'org.springframework.boot'
이 플러그인이 하위 모듈에 적용되면, 각 모듈은 Spring Boot 프로젝트처럼 동작합니다.
대표적으로:
bootJarbootRun
태스크가 생깁니다.
즉, 하위 모듈을 실행 가능한 Spring Boot 애플리케이션처럼 패키징할 수 있습니다.
5-3. io.spring.dependency-management 플러그인
apply plugin: 'io.spring.dependency-management'
이 플러그인은 하위 모듈의 의존성 버전들을 Spring Boot의 관리 체계에 맞추는 데 도움을 줍니다.
즉, 하위 모듈 각각이 공통된 버전 정책 아래에서 의존성을 해석하게 됩니다.
5-4. 여기서 중요한 구조적 의미 🚨
현재 이 코드는 모든 하위 모듈에 다음 세 플러그인을 적용합니다.
javaspring-bootdependency-management
즉, 하위 모듈 전부가 Spring Boot 애플리케이션처럼 취급될 가능성이 있습니다.
이건 입문용이나 단순 구조에서는 이해하기 쉽고 편합니다.
하지만 실무적으로는 조금 더 생각해봐야 합니다.
예를 들어:
module-api는 실행 모듈module-common은 공통 라이브러리 모듈module-domain은 도메인 로직만 담는 모듈
이라면 module-common, module-domain까지 전부 spring-boot 플러그인을 적용하는 것은 다소 과할 수 있습니다.
이 부분은 뒤에서 다시 설명드리겠습니다.
6. repositories 블록 설명 📚
repositories {
mavenCentral()
}
Gradle은 의존성을 어디에서 다운로드할지 알아야 합니다.
이 블록은 라이브러리를 찾을 저장소(repository) 를 지정합니다.
여기서는 mavenCentral()을 사용하고 있습니다.
즉:
- Spring Boot Starter
- Lombok
- JUnit
- Devtools
같은 라이브러리를 Maven Central 저장소에서 내려받겠다는 의미입니다.
왜 하위 모듈마다 이 설정이 필요한가?
하위 모듈이 라이브러리를 다운로드해야 하기 때문입니다.
subprojects {} 안에 넣어두면 모든 하위 모듈이 같은 저장소 설정을 공유합니다.
즉:
- 어느 모듈이든 같은 저장소를 쓴다
- 저장소 설정이 중복되지 않는다
라는 장점이 있습니다.
7. java { toolchain { ... } } 설명 ☕️
java {
toolchain {
languageVersion = JavaLanguageVersion.of(17)
}
}
이 설정은 모든 하위 모듈이 Java 17을 기준으로 빌드되도록 통일하는 설정입니다.
7-1. 왜 Java 버전을 명시해야 하는가?
개발 환경에서는 종종 이런 문제가 생깁니다.
- 어떤 개발자는 JDK 17 설치
- 어떤 개발자는 JDK 21 설치
- 어떤 서버는 JDK 17
- 어떤 IDE는 다른 JDK로 프로젝트를 엶
이렇게 되면 컴파일 결과가 달라지거나, 특정 문법/바이트코드 호환 문제가 생길 수 있습니다.
그래서 프로젝트가 명확하게 선언합니다.
"우리 프로젝트는 Java 17 기준이다."
7-2. toolchain이 단순 sourceCompatibility와 다른 점
예전에는 많이 이런 식으로 썼습니다.
sourceCompatibility = '17'
targetCompatibility = '17'
하지만 toolchain은 더 현대적인 방식입니다.
toolchain은 단순히 문법 버전만 맞추는 것이 아니라,
Gradle이 적절한 JDK 도구 체인을 사용하도록 유도합니다.
즉, 더 일관되고 안정적인 빌드를 가능하게 합니다.
7-3. JavaLanguageVersion.of(17)
languageVersion = JavaLanguageVersion.of(17)
이것은 빌드에 사용할 Java 언어 레벨이 17이라는 뜻입니다.
즉:
record,sealed같은 Java 17 기능- Java 17 바이트코드 타겟
- Java 17 기준 컴파일
을 의미합니다.
8. configurations 블록 설명 🧠
configurations {
compileOnly {
extendsFrom annotationProcessor
}
}
이 부분은 처음 보면 좀 난해합니다.
하지만 Lombok을 이해하면 왜 필요한지 보입니다.
8-1. configuration이란 무엇인가?
Gradle에서 configuration은
의존성을 어떤 목적/범위로 사용할지 구분하는 논리적 그룹입니다.
예를 들어:
implementation→ 실제 애플리케이션 코드에 필요한 라이브러리compileOnly→ 컴파일 시에만 필요하고 실행 시엔 필요 없는 라이브러리runtimeOnly→ 실행 시에만 필요testImplementation→ 테스트 코드에서만 필요annotationProcessor→ 애노테이션 처리용
즉, 의존성의 사용 범위(scope) 를 나누는 개념입니다.
8-2. compileOnly
compileOnly
이 범위의 라이브러리는 컴파일할 때만 필요하고, 최종 결과물에는 포함되지 않습니다.
대표적인 예가 Lombok입니다.
Lombok은 런타임 라이브러리라기보다,
컴파일 시점에 코드를 생성해주는 도구에 가깝습니다.
즉, .class 파일로 바뀌고 나면 Lombok 자체는 런타임에 없어도 되는 경우가 많습니다.
8-3. annotationProcessor
annotationProcessor
이건 애노테이션 처리기를 등록하는 configuration입니다.
예를 들어 Lombok은 다음 애노테이션들을 보고:
@Getter@Setter@Builder@NoArgsConstructor
컴파일 시점에 실제 메서드나 생성자 코드를 만들어냅니다.
이때 Lombok은 단순 라이브러리가 아니라 애노테이션 프로세서로 동작합니다.
그래서 다음 설정이 필요합니다.
annotationProcessor 'org.projectlombok:lombok'
8-4. compileOnly { extendsFrom annotationProcessor }의 의미
compileOnly {
extendsFrom annotationProcessor
}
이 뜻은:
annotationProcessor에 등록된 의존성을compileOnly 구성도 함께 참조하도록 하겠다
라는 의미입니다.
쉽게 말하면:
- Lombok을 애노테이션 프로세서로도 쓰고
- 컴파일용 의존성으로도 자연스럽게 연결하겠다
는 의도입니다.
실제로 Lombok 설정에서 자주 등장하는 패턴입니다.
9. dependencies 블록 설명 📦
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-web'
compileOnly 'org.projectlombok:lombok'
developmentOnly 'org.springframework.boot:spring-boot-devtools'
annotationProcessor 'org.projectlombok:lombok'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
testRuntimeOnly 'org.junit.platform:junit-platform-launcher'
}
이 블록은 하위 모듈들에 공통으로 들어갈 라이브러리를 정의합니다.
이제 각각을 하나씩 뜯어보겠습니다.
9-1. implementation 'org.springframework.boot:spring-boot-starter-web'
implementation 'org.springframework.boot:spring-boot-starter-web'
이건 Spring Boot에서 웹 애플리케이션을 만들기 위한 대표적인 스타터입니다.
보통 다음이 들어옵니다.
- Spring MVC
- DispatcherServlet
- Jackson
- Validation 관련 기본 구성
- Embedded Tomcat
- 기본 웹 서버 실행 환경
즉, 이 의존성이 있으면 해당 모듈은
REST API나 웹 애플리케이션을 만들 준비가 된 것입니다.
왜 implementation인가?
implementation은 이 모듈의 내부 구현에 필요한 라이브러리를 의미합니다.
즉, 소스 코드에서 직접 사용하고, 런타임에도 필요합니다.
웹 애플리케이션은 실행 시 Tomcat, Spring MVC 등이 필요하므로 implementation이 맞습니다.
중요한 실무 포인트 ⚠️
이 설정이 subprojects {} 안에 있다는 것은
모든 하위 모듈에 web starter가 들어간다는 뜻입니다.
즉:
module-apimodule-commonmodule-domain
모두 웹 의존성을 갖게 됩니다.
이건 간단한 프로젝트에서는 괜찮지만,
실무에서는 불필요한 경우가 많습니다.
예를 들어 공통 유틸 모듈에 굳이 Tomcat이나 MVC 관련 라이브러리가 들어갈 필요는 없기 때문입니다.
즉, 현재 구조는 단순화에는 좋지만, 세밀한 분리에는 불리할 수 있다는 점을 기억하셔야 합니다.
9-2. compileOnly 'org.projectlombok:lombok'
compileOnly 'org.projectlombok:lombok'
Lombok을 컴파일 시에만 사용하겠다는 의미입니다.
Lombok은 실행 시 동작하는 프레임워크라기보다
컴파일 시 코드를 생성하는 도구이므로 compileOnly가 일반적입니다.
즉:
- 개발자는
@Getter,@Builder등을 작성 - 컴파일러가 Lombok 프로세서를 통해 실제 코드 생성
- 최종 런타임에는 Lombok이 굳이 없어도 됨
이 구조입니다.
9-3. developmentOnly 'org.springframework.boot:spring-boot-devtools'
developmentOnly 'org.springframework.boot:spring-boot-devtools'
이 의존성은 개발 편의를 위한 도구입니다.
대표적으로:
- 코드 변경 감지 후 자동 재시작
- 개발 생산성 향상
- 개발 중 빠른 피드백
같은 기능을 제공합니다.
왜 developmentOnly인가?
개발할 때만 필요하고, 운영 서버에서는 필요하지 않기 때문입니다.
즉:
- 개발 환경에는 포함
- 배포/운영 환경에는 불필요
라는 의도를 명확히 표현한 것입니다.
이 범위 구분은 실무적으로 매우 좋습니다.
9-4. annotationProcessor 'org.projectlombok:lombok'
annotationProcessor 'org.projectlombok:lombok'
이건 Lombok을 애노테이션 프로세서로 등록하는 설정입니다.
이 설정이 있어야 컴파일 시 Lombok이 실제로 동작해서 코드를 생성합니다.
즉:
compileOnly만 있으면 충분하지 않음annotationProcessor도 함께 있어야 함
입니다.
9-5. testImplementation 'org.springframework.boot:spring-boot-starter-test'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
Spring Boot 테스트용 스타터입니다.
보통 다음이 포함됩니다.
- JUnit 5
- Mockito
- AssertJ
- Spring Test
- MockMvc 관련 테스트 지원
- JSON 테스트 지원
즉, 테스트 코드 작성에 필요한 대부분의 기본 도구가 들어 있습니다.
9-6. testRuntimeOnly 'org.junit.platform:junit-platform-launcher'
testRuntimeOnly 'org.junit.platform:junit-platform-launcher'
이건 테스트 실행 시점에 필요한 JUnit 플랫폼 런처입니다.
즉:
- 테스트 코드를 실행할 때 필요한 런타임 구성 요소
- 컴파일할 때는 직접 필요하지 않을 수 있음
- 실제 test task가 실행될 때 사용
이라는 의미입니다.
10. tasks.named('test') { ... } 설명 🧪
tasks.named('test') {
useJUnitPlatform()
}
이 설정은 테스트 태스크를 JUnit Platform 기반으로 실행하겠다는 뜻입니다.
10-1. tasks.named('test')
Gradle에는 test라는 기본 테스트 태스크가 있습니다.
이 코드는 그 test 태스크를 찾아서 추가 설정을 하는 것입니다.
즉:
"test 태스크에 대해 이렇게 동작하도록 설정할게"
라는 뜻입니다.
10-2. useJUnitPlatform()
이건 JUnit 5 기반 테스트 실행을 활성화합니다.
과거 JUnit 4와 다르게, JUnit 5는 JUnit Platform 위에서 동작합니다.
따라서 최신 Spring Boot 프로젝트에서는 거의 항상 이 설정이 들어갑니다.
즉:
@Test@DisplayName@Nested@ParameterizedTest
같은 JUnit 5 기능을 정상적으로 사용하려면 이 설정이 필요합니다.
11. 이 코드가 실제로 의미하는 전체 구조 🌍
이제 전체를 큰 그림으로 묶어보겠습니다.
이 루트 build.gradle은 사실상 다음 선언과 같습니다.
"우리 멀티 모듈 프로젝트의 모든 하위 모듈은
Java 17을 사용하고,
Spring Boot 플러그인을 적용받고,
Maven Central에서 라이브러리를 내려받으며,
Lombok과 Spring Web, Spring Test를 기본으로 사용하고,
테스트는 JUnit 5로 실행한다."
즉, 이 한 파일이 하위 모듈 전체의 공통 개발 표준을 정의하고 있습니다.
12. 이 구조의 장점 ✅
이 코드 구조는 몇 가지 큰 장점이 있습니다.
12-1. 중복 제거
각 하위 모듈마다 매번 아래 내용을 반복할 필요가 없습니다.
- Java 버전
- 저장소
- Spring Boot 플러그인
- Lombok
- 테스트 설정
즉, 공통 코드를 중앙에서 한 번만 작성하면 됩니다.
12-2. 표준화
모든 하위 모듈이 동일한 기준으로 빌드됩니다.
예:
- 모두 Java 17
- 모두 JUnit 5
- 모두 Maven Central
- 모두 같은 Spring Boot 플러그인 버전
실무에서 매우 중요합니다.
12-3. 유지보수 용이
버전을 바꾸고 싶다면 루트에서 한 번만 수정하면 됩니다.
예를 들어 Spring Boot 버전을 바꾸려면:
id 'org.springframework.boot' version '3.5.12' apply false
이 한 줄만 수정하면 됩니다.
13. 하지만 이 구조의 한계도 있습니다 ⚠️
이제 아주 중요한 실무 관점을 말씀드리겠습니다.
현재 구조는 모든 하위 모듈에 공통적으로 Spring Boot + Web 설정을 넣는 방식입니다.
이건 간단하고 직관적이지만, 모듈이 많아질수록 다소 거칠 수 있습니다.
문제 1. 모든 모듈이 웹 모듈이 되어버릴 수 있음
현재:
implementation 'org.springframework.boot:spring-boot-starter-web'
이 설정이 subprojects 안에 있으므로
모든 모듈이 웹 스타터를 갖게 됩니다.
그런데 공통 모듈이나 도메인 모듈은 보통 웹 서버 기능이 필요 없습니다.
즉, 필요 없는 라이브러리가 섞일 수 있습니다.
문제 2. 모든 모듈이 실행 모듈처럼 보일 수 있음
현재:
apply plugin: 'org.springframework.boot'
모든 모듈에 Spring Boot 플러그인이 적용됩니다.
그러면 bootJar 같은 태스크가 각 모듈에 생길 수 있습니다.
하지만 실무에서는 보통:
module-api→ 실행 모듈module-common→ 라이브러리 모듈module-domain→ 라이브러리 모듈
처럼 나눕니다.
즉, 모든 모듈에 bootJar가 필요한 것은 아닙니다.
14. 그래서 실무에서는 보통 어떻게 개선하는가? 🛠️
실무에선 대체로 다음처럼 분리합니다.
공통 설정은 유지
루트에서:
- Java 버전
- 저장소
- Lombok
- 테스트 설정
같은 것은 공통으로 둡니다.
실행 모듈에만 Spring Boot 적용
예를 들어 module-api/build.gradle에만:
plugins {
id 'org.springframework.boot'
id 'io.spring.dependency-management'
}
를 적용합니다.
반면 공통 모듈은:
plugins {
id 'java-library'
}
정도로 끝냅니다.
웹 의존성도 실행 모듈에만 둠
즉:
module-api에만spring-boot-starter-webmodule-common에는 없음module-domain에는 없음
으로 나누는 편이 더 깔끔합니다.
15. 이 코드를 학습 관점에서 해석하면 🎓
학습용으로는 아주 좋은 구조입니다.
왜냐하면:
- 멀티 모듈 개념이 직관적으로 보이고
- 하위 모듈 공통 설정이 어떻게 전파되는지 이해하기 쉽고
- 최소 코드로 바로 동작시킬 수 있기 때문입니다
즉, 입문자에게는 매우 설명하기 좋은 형태입니다.
다만 프로젝트가 커지면
공통화와 분리의 균형을 잡아야 합니다.
16. 한 줄씩 요약 정리 ✨
이제 마지막으로 각 블록을 아주 짧게 다시 정리해드리겠습니다.
plugins
plugins {
id 'org.springframework.boot' version '3.5.12' apply false
id 'io.spring.dependency-management' version '1.1.7' apply false
}
- 플러그인 버전을 루트에서 통일 관리
- 즉시 적용은 하지 않음
- 하위 모듈에서 사용할 준비만 해둠
group, version
group = 'com.intheeast'
version = '0.0.1-SNAPSHOT'
- 전체 프로젝트의 공통 식별자
- 하위 모듈이 기본적으로 상속받음
subprojects
subprojects {
- 모든 하위 모듈에 공통 설정 적용
apply plugin
apply plugin: 'java'
apply plugin: 'org.springframework.boot'
apply plugin: 'io.spring.dependency-management'
- 하위 모듈을 Java + Spring Boot 프로젝트로 동작하게 함
repositories
repositories {
mavenCentral()
}
- 의존성 다운로드 위치 지정
java.toolchain
java {
toolchain {
languageVersion = JavaLanguageVersion.of(17)
}
}
- 모든 하위 모듈의 Java 버전을 17로 통일
configurations
configurations {
compileOnly {
extendsFrom annotationProcessor
}
}
- Lombok 같은 애노테이션 프로세서 연동 편의 설정
dependencies
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-web'
compileOnly 'org.projectlombok:lombok'
developmentOnly 'org.springframework.boot:spring-boot-devtools'
annotationProcessor 'org.projectlombok:lombok'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
testRuntimeOnly 'org.junit.platform:junit-platform-launcher'
}
- 웹, Lombok, 개발도구, 테스트 라이브러리 공통 적용
test
tasks.named('test') {
useJUnitPlatform()
}
- 모든 하위 모듈 테스트를 JUnit 5로 실행
17. 결론 🎯
이 build.gradle은 멀티 모듈 프로젝트에서 루트가 공통 규칙을 정의하고, 하위 모듈들이 그 규칙을 상속받는 구조를 잘 보여주는 예제입니다.
핵심은 다음입니다.
- 루트는 버전과 공통 설정을 관리한다
- 하위 모듈은 중복 없이 공통 정책을 적용받는다
- Java 버전, 저장소, 의존성, 테스트 정책이 통일된다
- 단, 현재 구조는 모든 모듈을 Spring Boot 웹 모듈처럼 취급하므로 실무에선 더 세밀하게 분리할 필요가 있다
즉, 이 코드는 멀티 모듈 학습용/초기 구성용으로는 매우 좋고,
실무형으로 발전시키려면 실행 모듈과 라이브러리 모듈을 분리하는 리팩토링이 다음 단계라고 보시면 됩니다.
'gradle' 카테고리의 다른 글
| Creating a Multi Module Project[4] (0) | 2026.03.30 |
|---|---|
| Creating a Multi Module Project[3] (0) | 2026.03.25 |
| Creating a Multi Module Project[2] (0) | 2026.03.24 |
| Creating a Multi Module Project[1] (0) | 2026.03.24 |
| sync build.gradle (0) | 2026.03.23 |