개요
대규모 애플리케이션에서는 유지보수와 확장성을 고려해 프로젝트를 모듈로 나누는 경우가 있다.
이번 글에서는 Spring Boot 멀티모듈 프로젝트를 설계하고 구성하는 방법을 작성했다.
멀티모듈 프로젝트?
멀티모듈 프로젝트는 하나의 루트 프로젝트 아래에 여러 서브모듈을 포함하는 프로젝트 구조이다.
각 모듈은 독립적으로 개발 및 배포될 수 있지만, 상호 간에 의존성을 가질 수 있다.
왜 멀티모듈 프로젝트를 사용하는가?
- 모듈화: 비즈니스 로직을 분리하여 코드 유지보수성을 높인다.
- 재사용성: 공통 모듈을 여러 프로젝트에서 재사용할 수 있다.
- 협업 용이성: 팀원이 서로 다른 모듈을 독립적으로 개발할 수 있다.
- 빌드 최적화: 특정 모듈만 빌드하거나 테스트할 수 있다.
프로젝트 구조
spring-multi-module-project
│
├── build.gradle # 루트 프로젝트의 빌드 스크립트
├── settings.gradle
│
├── module-api # API 모듈
│ ├── build.gradle
│ └── src
│
├── module-core # 공통 모듈 (비즈니스 로직, 엔티티)
│ ├── build.gradle
│ └── src
│
├── module-web # 웹 모듈 (컨트롤러, View)
│ ├── build.gradle
│ └── src
설정
1. 루트 프로젝트 설정
settings.gradle
rootProject.name = 'spring-multi-module-project'
include 'module-api'
include 'module-core'
include 'module-web'
build.gradle
plugins {
id 'java'
id 'org.springframework.boot' version '3.1.0'
id 'io.spring.dependency-management' version '1.1.0'
}
allprojects {
group = 'com.example'
version = '1.0.0'
repositories {
mavenCentral()
}
}
subprojects {
apply plugin: 'java'
sourceCompatibility = '17'
targetCompatibility = '17'
dependencies {
testImplementation 'org.springframework.boot:spring-boot-starter-test'
}
}
2. 공통 모듈 설정
module-core/build.gradle
dependencies {
implementation 'org.springframework.boot:spring-boot-starter'
}
예제 코드 : module-core/src/main/java/com/example/core/DomainModel.java
package com.example.core;
public class DomainModel {
private String name;
public DomainModel(String name) {
this.name = name;
}
public String getName() {
return name;
}
}
3. API 모듈 설정
module-api/build.gradle
dependencies {
implementation project(':module-core') // core 모듈 의존성 추가
implementation 'org.springframework.boot:spring-boot-starter-web'
}
예제 코드: module-api/src/main/java/com/example/api/ApiController.java
package com.example.api;
import com.example.core.DomainModel;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class ApiController {
@GetMapping("/api/domain")
public String getDomain() {
DomainModel model = new DomainModel("Example Domain");
return "Domain Name: " + model.getName();
}
}
4. 웹 모듈 설정
module-web/build.gradle
dependencies {
implementation project(':module-core') // core 모듈 의존성 추가
implementation project(':module-api') // api 모듈 의존성 추가
implementation 'org.springframework.boot:spring-boot-starter-thymeleaf'
}
예제 코드: module-web/src/main/java/com/example/web/WebController.java
package com.example.web;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
@Controller
public class WebController {
@GetMapping("/")
public String home(Model model) {
model.addAttribute("message", "Welcome to the Web Module!");
return "index";
}
}
HTML 파일: module-web/src/main/resources/templates/index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Web Module</title>
</head>
<body>
<h1>Message: ${message}</h1>
</body>
</html>
빌드 및 실행
1. 전체 빌드
./gradlew build
2. 개별 모듈 빌드
./gradlew :module-api:build
3. 실행
./gradlew :module-web:bootRun
실제 사용 시
의존성 관리
각 모듈이 core 모듈을 참조하도록 설계하면 중복 코드를 줄일 수 있다.
의존성 순환 문제를 방지하기 위해 의존 관계를 잘 설계해야 한다.
테스트 분리
각 모듈에서 독립적인 테스트를 작성하고 실행할 수 있도록 분리한다.
core 모듈에는 비즈니스 로직 테스트, api 모듈에는 API 테스트를 작성한다.
CI/CD 통합
멀티모듈 프로젝트에서는 특정 모듈만 변경된 경우 해당 모듈만 빌드하도록 CI 파이프라인을 설계해야 한다.
버전 관리
공통 모듈을 별도의 라이브러리로 관리하거나, 멀티모듈로 유지하면서 버전 태그를 관리할 수 있다.
문의사항이나 피드백은 댓글로 남겨주세요.
'프로그래밍 언어 > JAVA, SPRING' 카테고리의 다른 글
[SPRING BATCH] 1. 스프링 배치란 (0) | 2024.12.04 |
---|---|
[SPRING BOOT] WebSocket과 Redis를 활용한 실시간 채팅 시스템 구축하기 (0) | 2024.11.26 |
[SPRING BOOT] CORS 에러와 DELETE요청 해결하기 (0) | 2024.11.26 |
[SPRING BOOT] UnrecognizedPropertyException 해결하기 (0) | 2024.11.26 |
[JAVA] Exception Handling (0) | 2024.07.22 |