(MSA)1.프로젝트 멀티모듈 구성

Published: by Creative Commons Licence

🧱 Spring Boot 멀티모듈 프로젝트 구성 정리

Spring Boot 기반의 멀티모듈 프로젝트를 구성하면서, 루트 및 각 모듈의 build.gradlesettings.gradle 설정을 어떻게 구성했는지, 그리고 그 이유에 대해 상세히 정리합니다.


📂 전체 프로젝트 구조

dream
├── build.gradle
├── settings.gradle
├── common
│   └── build.gradle
├── auth
│   └── build.gradle
├── product
│   └── build.gradle
└── payment
    └── build.gradle

⚙️ settings.gradle

pluginManagement {
    repositories {
        maven { url 'https://repo.spring.io/milestone' }
        maven { url 'https://repo.spring.io/snapshot' }
        gradlePluginPortal()
    }
}
rootProject.name = 'dream'
include 'common'
include 'auth'
include 'product'
include 'payment'

설명

  • pluginManagement: 플러그인을 어디서 받을지 정의. 실험적 플러그인 사용을 위해 Spring milestone/snapshot 저장소도 추가.
  • rootProject.name: 루트 프로젝트의 이름을 dream으로 설정.
  • include: 하위 모듈(common, auth, product, payment)을 명시적으로 포함.

🏠 루트 build.gradle

plugins {
    id 'java'
    id 'org.springframework.boot' version '3.5.0-SNAPSHOT'
    id 'io.spring.dependency-management' version '1.1.7'
}

group = 'com.enjoywalk'
version = '0.0.1-SNAPSHOT'

java {
    toolchain {
        languageVersion = JavaLanguageVersion.of(21)
    }
}

configurations {
    compileOnly {
        extendsFrom annotationProcessor
    }
}

repositories {
    mavenCentral()
    maven { url 'https://repo.spring.io/milestone' }
    maven { url 'https://repo.spring.io/snapshot' }
}

tasks.named('bootJar') {
    enabled = false
}

tasks.named('jar') {
    enabled = false
}

subprojects {
    apply plugin: 'java'

    repositories {
        mavenCentral()
        maven { url 'https://repo.spring.io/milestone' }
        maven { url 'https://repo.spring.io/snapshot' }
        maven { url 'https://repo.spring.io/release' }
    }

    group = 'com.enjoywalk'
    version = '0.0.1-SNAPSHOT'

    java {
        toolchain {
            languageVersion = JavaLanguageVersion.of(21)
        }
    }

    dependencies {
        // == Lombok ==
        compileOnly 'org.projectlombok:lombok'
        annotationProcessor 'org.projectlombok:lombok'

        // == DB ==
        runtimeOnly 'com.mysql:mysql-connector-j'
        implementation 'com.zaxxer:HikariCP'

        // == Test ==
        testImplementation 'org.springframework.boot:spring-boot-starter-test'
        testRuntimeOnly 'org.junit.platform:junit-platform-launcher'

        // logging
        implementation 'com.github.gavlyukovskiy:p6spy-spring-boot-starter:1.8.0'
    }

    tasks.named('test') {
        useJUnitPlatform()
    }
}

configure([project(":auth"), project(":product"), project(":payment")]) {
    dependencies {
        // == Spring Boot Starters ==
        implementation 'org.springframework.boot:spring-boot-starter-web'
        implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
        implementation 'org.springframework.boot:spring-boot-starter-validation'

        // == Jackson (JSON 처리) ==
        implementation 'com.fasterxml.jackson.core:jackson-databind'

        // MapStruct
        implementation 'org.mapstruct:mapstruct:1.5.3.Final'
        annotationProcessor 'org.mapstruct:mapstruct-processor:1.5.3.Final'
        implementation 'org.mapstruct.extensions.spring:mapstruct-spring-annotations:1.1.2'
        annotationProcessor 'org.mapstruct.extensions.spring:mapstruct-spring-extensions:1.1.2'

        // SWAGGER
        implementation 'org.springdoc:springdoc-openapi-starter-webmvc-ui:2.2.0' // Swagger UI
    }
}

설명

  • [subprojects] 하위 모든 모듈에 공통적으로 적용할 설정 정의 (플러그인, JDK, 테스트, 저장소 등)
  • [configure] auth, product, payment 모듈에 공통으로 적용할 의존성 정의.
  • [configure] Lombok, Web, JPA, Validation, Test 관련 공통 설정 subprojects 포함.

📁 common/build.gradle

plugins {
    id 'java-library'
    id 'org.springframework.boot'
    id 'io.spring.dependency-management'
}

dependencies {
    implementation 'org.springframework.boot:spring-boot-starter-web'
    implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
    implementation 'org.springframework.boot:spring-boot-starter-validation'
}

tasks.named('bootJar') {
    enabled = false
}
tasks.named('jar') {
    enabled = true
}

설명

  • java-library: 다른 모듈이 common을 참조할 수 있도록 하기 위한 플러그인.
  • jar 활성화: 실제 사용할 수 있도록 아카이브 생성 필요.
  • common 모듈은 Spring Boot 실행 모듈이 아니므로 bootJar 비활성화.
  • 최초 common 모듈은 Spring 관련 설정은 없을 것으로 생가해서 id 'org.springframework.boot', id 'io.spring.dependency-management' 를 plugins 에서 제외했었는데 MySqlDataSourceConfig 파일이 들어오면서 Spring 관련 설정이 포함되도록 변경.

📁 auth / product / payment (공통 구조)

plugins {
    id 'java'
    id 'org.springframework.boot'
    id 'io.spring.dependency-management'
}

dependencies {
    implementation project(':common') // common 모듈 의존성 추가
    implementation 'org.springframework.boot:spring-boot-starter-security'
    implementation 'io.jsonwebtoken:jjwt-api:0.11.5'
    runtimeOnly 'io.jsonwebtoken:jjwt-impl:0.11.5'
    runtimeOnly 'io.jsonwebtoken:jjwt-jackson:0.11.5' // JSON 처리용

    runtimeOnly 'com.h2database:h2'
}

설명

  • 실행 가능한 Spring Boot 모듈이므로 관련 플러그인 적용.
  • common 모듈을 의존성으로 포함하여 공통 코드 재사용 가능.
  • SpringSecurity, JWT 관련 의존성 추가
  • 개발 DB 방화벽 문제로 접속이 안되는 경우 로컬에서 개발 가능하도록 h2 DB 추가.

✅ 정리

  • 공통 설정은 루트 build.gradle + subprojects로, 중복 제거.
  • 실행 모듈에만 Spring Boot 관련 의존성 적용.
  • common은 재사용 가능한 코드 묶음(JAR로 생성).
  • 멀티모듈 구조는 확장성, 협업, 유지보수성 측면에서 큰 장점을 가짐.