티스토리 뷰

개발 환경
Spring Boot 3.4.5
Java 17
IntelliJ
MacOS
멀티 모듈인데 여러개 기동할 수 있는걸 알았나?
처음 멀티 모듈을 접했을 때는 한 프로젝트 안에 여러 모듈을 두고 API 모듈에 여러개를 끌고와서 사용하는 것으로만 배웠다.
하지만, 내가 실무에서 Express.js를 하다가 운이 좋게 다른 파트로가서 스프링 프로젝트를 접했는데
프로젝트 안에 모듈이 여러개로 나뉘어져 Application을 여러개를 기동시키고 있었다.
물론 로컬에서도 여러개 기동해야하는 귀찮음은 있었지만, 오히려 코드를 찾아가기에는 정말 편했고, 이렇게 하면 유지보수도 좋을 것이라고 느꼈다.
굳이 여러개 프로젝트 안만들고 개발하면 되잖아!?

프로젝트 모듈 구조
이전에 했던 작성 글입니다.
처음에는 이것과 같이 API, Domain, External, Common 모듈로만 구성을 해보았는데 정작 실무에서는 멀티 모듈로 한개만 기동하는 것이 아닌 여러 개를 기동하는 형태로 진행되었습니다.
[백엔드/🌸Spring] - [Spring] 멀티 모듈 설계 : 도메인, API, 테스트 환경 세팅 전략까지
[Spring] 멀티 모듈 설계 : 도메인, API, 테스트 환경 세팅 전략까지
들어가기 전 현재 작성된 코드들은 GitHub 에 저장되어 있습니다.이해가 안되는 부분이 있다면 번갈아 가며 확인해주시면 됩니다. 개발 환경 Spring Boot 3.4.5Java 17IntelliJMacOS 왜 멀티 모듈을 선택했나
coasis.tistory.com
따라서, 이번엔 색다르게(실무에 맞게..?) 구성하려고 합니다.
저는 아래와 같이 모듈로 세팅하게 되었습니다.
multimodule-project
│
├── build.gradle (루트)
├── settings.gradle
│
├── domain # JPA Entity, Repository
│ └── build.gradle
│
├── api # Controller, Service
│ └── build.gradle
│
├── cms # 관리자 페이지
│ └── build.gradle
│
├── batch # 배치
│ └── build.gradle
│
└── external # 외부 호출
└── build.gradle
- domain 모듈 : Domain(Entity), Enum, Repository, QueryDsl
- api 모듈 : Controller 및 service, Advice, Config, 필터, 인터셉터, 스케쥴러
- cms 모듈 : 관리자 페이지 즉, 콘텐츠 관리 페이지
- batch 모듈 : 스프링 배치 모듈
- external 모듈 : 외부 시스템 연동 (S3, AI, Redis 등)
멀티 모듈 프로젝트 세팅하기
우선 공식이에서 글을 보면 멀티 프로젝트 레이아웃은 아래와 같이 해야합니다.
https://docs.gradle.org/current/userguide/multi_project_builds.html
Multi-Project Builds
As projects grow, it’s common to split them into smaller, focused modules that are built, tested, and released together. Gradle supports this through multi-project builds, allowing you to organize related codebases under a single build while keeping each
docs.gradle.org

자 이제 비슷하게 세팅해볼까요~?

먼가 되게 많은데 되게 귀찮지만 별 것 없습니다.
Root 프로젝트에 있는 src를 삭제한 후 Root에서 모듈을 생성하여 넣어주기만 하면 됩니다.

솔직히 여기까지는 누구든 아무나 갓 개발 2개월 시작한 사람도 세팅할 수 있는 것 같습니다.
저도 어디에서 막혔나면 gradle.build를 작성하는 것에서 막히게 되었습니다.

너가 build.gradle를 알어!?
공식이를 보면 이 번호 순서대로 읽어들인다고 보시면 됩니다.
그래서 이 순서대로 어떻게 세팅했고 세팅한 의미가 뭔지 알려드리도록하겠습니다.
![[그림6] gradle 정의 순서](https://blog.kakaocdn.net/dna/LP1jQ/btsQiIVmWS4/AAAAAAAAAAAAAAAAAAAAAI_FrouEkB2J6ANUMY9cxphYHyii89Ujy0MTS8Bv57ck/img.png?credential=yqXZFxpELC7KVnFOS48ylbz2pIh7yKj8&expires=1767193199&allow_ip=&allow_referer=&signature=XevlUAA1iyK8cLy1l2Rx3zxrSfY%3D)
1. Root프로젝트의 settings.gradle
이 멀티 모듈에서 서브프로젝트들이 무엇이 있는지 선언하는 것입니다.
rootProject.name = 'myprojectName'
include 'cms'
include 'api'
include 'domain'
include 'external'
include 'batch'
2. Root프로젝트의 build.gradle
plugins {
id 'java'
id 'org.springframework.boot' version '3.4.5'
id 'io.spring.dependency-management' version '1.1.7'
}
bootJar.enabled = false
allprojects {
group = 'com.aoxx' // 공통 group (패키지)
repositories {
mavenCentral()
}
java {
toolchain {
languageVersion = JavaLanguageVersion.of(17)
}
}
}
subprojects {
apply plugin: 'java'
apply plugin: 'org.springframework.boot'
apply plugin: 'io.spring.dependency-management'
}
- plugins 를 보면 이 프로젝트는 Java를 사용하고 Spring Boot 3.4.5 버전을 사용하고 의존성 관리 버전이 1.1.7인 것을 선언
- bootJar 는 Spring Boot 애플리케이션 실행 가능여부를 설정, 그래서 루트 프로젝트에서는 bootJar를 꺼줬습니다.
- allprojects 는 모든 프로젝트 (루트 + 서브모듈)에 공통 적용합니다.
- allprojects 의 repositories { mavenCentral() }은 외부 라이브러리 다운로드할 저장소를 선언
- allprojects 의 java { toolchain { languageVersion = 17 } } 은 로컬에 설치된 JDK 버전과 상관없이 Gradle이 지정한 Java17을 사용하도록 보장
3. domain 모듈의 build.gradle
plugins {
}
// 일반 라이브러리 Jar 활성화
bootJar.enabled = false
jar.enabled = true
dependencies {
// Lombok
compileOnly 'org.projectlombok:lombok'
annotationProcessor 'org.projectlombok:lombok'
// JPA
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
// PostgreSQL Driver
runtimeOnly 'org.postgresql:postgresql'
// 테스트용 H2
testImplementation 'com.h2database:h2'
runtimeOnly 'com.h2database:h2'
// Spring Boot Test (JUnit5 포함)
testImplementation 'org.springframework.boot:spring-boot-starter-test'
}
test {
useJUnitPlatform()
}
- domain 의 모듈은 별도로 실행하지 않고 Java 라이브러리 형태로 진행할 것이기 때문에 bootJar를 꺼주고 jar를 활성화 해주었습니다.
- dependencies 에는 ORM의 JPA와 DB와 직접적으로 연결될 것이기 때문에 Lombok, JPA, PostgreSQL Driver를 추가해 주었습니다.
- dependencies 에는 테스트 코드를 작성하기 위해 테스트 관련 의존성도 추가하였습니다.
4. cms 모듈의 build.gradle
plugins {
}
// 실행 모듈용
bootJar.enabled = true
jar.enabled = false
version = '1.0.0-cms' // 모듈별 version
dependencies {
implementation project(':domain')
implementation project(':external')
// Lombok
compileOnly 'org.projectlombok:lombok'
annotationProcessor 'org.projectlombok:lombok'
// Spring Boot
implementation 'org.springframework.boot:spring-boot-starter-web'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
// JPA
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
// 테스트용 H2
testImplementation 'com.h2database:h2'
runtimeOnly 'com.h2database:h2'
// Spring Boot Test (JUnit5, Mockito)
testImplementation 'org.springframework.boot:spring-boot-starter-test'
}
test {
useJUnitPlatform()
}
- 멀티 프로젝트에서 여러개를 실행한다고 했었는데 그중 1개 입니다.
- 애플리케이션 실행 가능하도록 bootJar를 활성화 해주었고, 라이브러리처럼 사용하는 jar는 꺼주었습니다.
- dependencies 의 implementation project들은 라이브러리 처럼 사용할 모듈들을 의존성 추가한 것입니다.
- dependencies 에서 동일하게 사용할 Lombok, Spring Boot, test 관련 의존성을 추가해 주었습니다.
- dependencies 에서 왜 JPA 의존성을 추가하였나면 JPA 메서드를 사용할 수 있게 cms 모듈에도 선언 해주었습니다.
5. api 모듈의 build.gradle
plugins {
}
// 실행 모듈용
bootJar.enabled = true
jar.enabled = false
version = '1.0.0-api' // 모듈별 version
dependencies {
implementation project(':domain')
implementation project(':external')
// Lombok
compileOnly 'org.projectlombok:lombok'
annotationProcessor 'org.projectlombok:lombok'
// Spring Boot
implementation 'org.springframework.boot:spring-boot-starter-web'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
// 테스트용 H2
testImplementation 'com.h2database:h2'
runtimeOnly 'com.h2database:h2'
// Spring Boot Test (JUnit5, Mockito)
testImplementation 'org.springframework.boot:spring-boot-starter-test'
}
test {
useJUnitPlatform()
}
- 멀티 프로젝트에서 여러개를 실행한다고 했었는데 그중 1개 입니다.
- 애플리케이션 실행 가능하도록 bootJar를 활성화 해주었고, 라이브러리처럼 사용하는 jar는 꺼주었습니다.
- dependencies 의 implementation project들은 라이브러리 처럼 사용할 모듈들을 의존성 추가한 것입니다.
- dependencies 에서 동일하게 사용할 Lombok, Spring Boot, test 관련 의존성을 추가해 주었습니다.
- 이후에 API 모듈에서도 JPA 메서드가 필요하다면 JPA 의존성을 추가해야겠죠.
6. batch 모듈의 build.gradle
plugins {
}
// 실행 모듈용
bootJar.enabled = true
jar.enabled = false
version = '1.0.0-batch' // 모듈별 version
dependencies {
implementation project(':domain')
implementation project(':external')
// Spring Boot
implementation 'org.springframework.boot:spring-boot-starter'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
// 테스트용 H2
testImplementation 'com.h2database:h2'
runtimeOnly 'com.h2database:h2'
// Spring Boot Test (JUnit5, Mockito)
testImplementation 'org.springframework.boot:spring-boot-starter-test'
// batch 모듈만 추가 (batch 테스트용)
testImplementation 'org.springframework.batch:spring-batch-test'
}
test {
useJUnitPlatform()
}
- 멀티 프로젝트에서 여러개를 실행한다고 했었는데 그중 1개 입니다.
- 스프링 배치 테스트 코드를 작성하기 위해 배치 테스트 의존성을 추가하였습니다.
Tip) jar : 다른 모듈이 의존할 수 있는 라이브러리 역할을 함, bootJar : Spring Boot 애플리케이션 실행형 jar
실행 모듈 기동 방법
그냥 IDE에서 모듈에 있는 Application을 만들어 main 메서드를 만들고 실행시켜보는 방법도 있습니다.

그럼 위와 같이 IntelliJ라면 여러개가 실행되어 중지에 숫자가 여러개 뜨는 것을 볼 수 있습니다.
자 이제 개발 시작~~ 하면 될 것이고,
우와 개발을 다 끝내서 이제 배포까지 공부해서 여차저차 했다고 합시다!
근데 이렇게 멀티 모듈로 되어 있는 것을 배포해서 기동하려면 어떻게 해야할까!?
아래와 같은 명령어를 터미널에서 줘 봤습니다. 어차피 배포하여 서버에서 아래와 같이 실행을 시켜줄 테니까요!!
# 실행 가능한 JAR 빌드
./gradlew :cms:bootJar
java -jar cms/build/libs/cms-1.0.0-cms.jar


허허 이렇게 배포하면 에러가 올라와서 큰일 납니다.
서버에 환경변수를 등록하거나 기동 시킬 때 환경 변수를 추가하여 스프링을 기동하면 될 것입니다.

감사합니다.
'백엔드 > 🌸Spring' 카테고리의 다른 글
| [Spring] schema.sql, data.sql이 적용 안될 때와 그에 맞는 JPA ddl-auto 설정 (0) | 2025.12.29 |
|---|---|
| [Spring] 실무에서 쓰는 JPA 페이징 전략: Pageable, DTO, MyBatis 비교까지 (0) | 2025.09.08 |
| [Spring] API 서버에서 카카오 로그인 구현 (2/2) : 토큰 받고 사용자 정보 조회 (1) | 2025.06.15 |
| [Spring] API 서버에서 카카오 로그인 구현 (1/2) : 인가 코드 받기 (1) | 2025.05.19 |
| [Spring] 멀티 모듈 설계 : 도메인, API, 테스트 환경 세팅 전략까지 (1) | 2025.05.13 |
- Total
- Today
- Yesterday
- 계단 오르기
- BFS
- 개발환경
- Fetch
- 디자인패턴
- java
- Flutter
- Cors
- 카카오 로그인
- 그리디
- Front
- spring
- 멀티모듈
- 실시간 채팅
- aws
- JPA 페이징
- 트랜잭션
- DART
- 네트워크
- 알고리즘
- 개발블로그
- JavaScript
- 코딩테스트
- 시간 객체
- 깃허브 액션
- 개발자
- 프로세스
- DBeaver
- 데이터 베이스
- 소셜로그인
| 일 | 월 | 화 | 수 | 목 | 금 | 토 |
|---|---|---|---|---|---|---|
| 1 | 2 | 3 | 4 | 5 | 6 | |
| 7 | 8 | 9 | 10 | 11 | 12 | 13 |
| 14 | 15 | 16 | 17 | 18 | 19 | 20 |
| 21 | 22 | 23 | 24 | 25 | 26 | 27 |
| 28 | 29 | 30 | 31 |
