* 모듈(Module) : 독립적으로 배포될 수 있는 코드의 단위

멀티 모듈(Multi-Module) : 코드 뭉치를 하나의 프로젝트 안에서 관리하는것

모듈별 책임을 분리하고 유지보수성과 확장성을 확보하기 위해 멀티모듈을 도입

멀티모듈의 설계 / 구조는 계층 기반으로 구성
하나의 프로젝트를 여러 개의 모듈로 나누어 관리
최상위 프로젝트(root)와  여러 개의 하위 모듈(module)로 구성

project-root/
├── module-api/
│   ├── controller/
│   ├── dto/
│   ├── resources/
│   └── build.gradle
├── module-service/
│   ├── service/
│   ├── utils/
│   └── build.gradle
├── module-domain/
│   ├── entity/
│   ├── repository/
│   └── build.gradle
├── module-core/
│   ├── conf/
│   ├── utils/
│   └── build.gradle
└── build.gradle (루트 설정)

project-root: 전체 프로젝트를 대표하는 루트 프로젝트로, 공통적인 빌드 설정을 관리
module-*: 각 모듈은 서로 다른 기능을 담당
	module-api: 컨트롤러 및 외부와의 통신을 처리
	module-service: 비즈니스 로직과 서비스 계층을 관리
	module-domain: 데이터 모델 및 데이터 접근 계층을 관리
	module-core: 공통 모듈로, 여러 모듈에서 재사용 가능한 유틸리티 및 설정 포함

 

멀티모듈의 주요 특징

1.	모듈화로 인해 코드 분리가 명확함
		각 모듈은 특정한 책임만을 가지며 서로 독립적
		결합도를 낮추고 응집도를 높이는 설계가 가능
2.	재사용성
		공통적인 로직이나 유틸리티를 module-core 같은 공통 모듈에 작성하여, 다른 모듈에서 재사용 가능
3.	빌드 및 배포 효율성
		변경 사항이 있는 모듈만 빌드하여 배포할 수 있어 빌드 시간을 단축
		Gradle이나 Maven을 사용하면 하위 모듈의 의존성과 빌드 순서를 관리 가능
4.	팀 협업 효율성
		각 팀이 서로 다른 모듈을 개발하도록 나누어 작업 가능
		충돌을 최소화하고 생산성 증가

 

멀티모듈 프로젝트의 장점

유지보수성: 각 모듈이 독립적이므로 변경 사항의 영향 범위가 작음
확장성: 새로운 기능을 추가할 때, 기존 모듈에 영향을 주지 않고 새로운 모듈로 추가 가능
재사용성: 특정 모듈을 여러 프로젝트에서 재사용 가능
의존성 관리: 각 모듈이 개별적으로 의존성을 관리하므로 필요하지 않은 의존성을 배제할 수 있음

 

경험한 어려움 및 해결 방안

경험한 어려움 및 해결 방안 
1: 의존성 관리의 어려움
module-service에서도 @Transactional을 사용하려면 spring-boot-starter-data-jpa가 필요
해결 : JPA 의존성을 추가

2. 멀티모듈 간 의존성 순환 문제 
module-core는 최대한 독립적으로 설계하고 PoJo 기반 순수 자바 클래스로 구성
단방향 의존성을 유지하여 의존성 순환 방지 

3. 멀티모듈에서 공통 설정 (Config 파일) 관리
공통 모듈의 역할을 명확하게 정리 → module-core가 비대해지지 않도록 주의

*. Config 위치
	api 로 가는 경우
		- WebMvcConfig: API 요청/응답 설정 (예: 메시지 컨버터, CORS 등)
		- SwaggerConfig: Swagger 문서화 설정
		- SecurityConfig: API 인증/인가 관련 설정 (Spring Security, OAuth)
		- RestTemplateConfig: 외부 API 호출을 위한 RestTemplate 설정
	core 로 가는 경우 
		- LoggingConfig: 로깅 설정
		- GlobalExceptionHandler: 전역 예외 처리
		- CommonConstants: 프로젝트 전반에서 사용하는 상수들
		- EncryptionConfig: 암호화 관련 공통 설정
  그 외 
		- feign : service 또는 (특정 API 모듈에서만 사용된다면) api 
		- Redis  : 	캐싱 또는 비즈니스 로직과 관련(service), 또는 core
		- JPA Config (Audit 등) : domain

 

 


 

멀티 모듈 적용

1. 모듈단위로 잘게 쪼개서 사용하고 싶어서 사용 (재활용) 

2. api / consumer(kafka) / batch  > service > domain > common
	- 엔트리포인트(=접근하는 컨트롤러) 부터 시작
    - core(=common)에는 어떤 엔트리포인트에도 문제없는(=특정기술에 종속 X) 순수한 포조객체 , Utils 메소드
    - domain에는 POJO(plain old Java Object), pojo + entity = jpa entity
    - 항상 단방향 ex. service 모듈 에서 common implement

 

멀티 모듈 회고

1. Api 모듈
	- api 모듈은 프로젝트의 엔트리 포인트
	- 외부로부터의 요청을 처리하는 컨트롤러와 데이터 전달을 위한 객체인 DTO(Data Transfer Object) 포함
    - 그 외 AOP, 공통 설정, 예외 처리 등을 포함 
    - 최상위 계층으로 외부와의 직접적인 인터페이스 역할을 하며, 모든 하위 모듈을 참조할 수 있는 구조로 설계
    - API의 단순히 요청을 라우팅하고 데이터를 가공하는 역할에 집중해야 한다고 생각
    - 그 외 추가적으로 배치, 컨슈머와 같은 다른 엔트리 포인트와도 구조적으로 통일성을 유지

2. Service 
	- 핵심 비즈니스 로직을 처리하고 데이터의 흐름을 제어하는 중간 계층
    - Domain 모듈과 협력하여 데이터 조작 및 검증을 처리하며, API 모듈로부터 요청을 전달받아 로직을 수행
    - 단방향 의존성을 유지하면서 Core 및 Domain 모듈만 참조
    - VO(Value Object) 비즈니스 로직과 관련된 값 객체를 포함 


3. Domain 모듈
	- 프로젝트의 핵심 데이터를 정의하고, 데이터 접근 계층을 처리하는 중요한 역할
	- POJO 기반의 엔티티와 JPA를 활용한 레포지토리 계층으로 구성
    - 특정 비즈니스 로직이 없는 순수한 데이터 계층으로 유지
    - module-core만 참조하도록 설계하여, 특정 비즈니스 로직이 없는 순수한 데이터 계층으로 유지
    - 다른 모듈에서 도메인 객체를 재사용할 수 있도록 돕고, 데이터 계층과 비즈니스 로직 간의 결합도를 낮춤
    - JPA 엔티티와 레포지토리를 포함하여 특정 기술 스택(JPA)에 종속적일 수 있음

4. Core 모듈
	- 공통적으로 사용되는 유틸리티와 설정을 모아둔 가장 하위 계층
    - 특정 기술 스택에 종속되지 않고, 
    배치 작업이나 다른 엔트리 포인트에서도 독립적으로 활용될 수 있도록 POJO 기반의 순수한 자바 클래스로 구성
    - 모든 모듈에서 재사용 가능한 코드를 포함하며, JPA와 같은 기술 의존성을 철저히 배제
    - 기술 변경이나 새로운 기능 추가 시에도 유연하게 대응할 수 있도록 설계
    - ex. 공통 예외 처리나 유틸 메서드처럼 어디서나 필요한 기능

5. Config 위치
	api 로 가는 경우
		- WebMvcConfig: API 요청/응답 설정 (예: 메시지 컨버터, CORS 등)
		- SwaggerConfig: Swagger 문서화 설정
		- SecurityConfig: API 인증/인가 관련 설정 (Spring Security, OAuth)
		- RestTemplateConfig: 외부 API 호출을 위한 RestTemplate 설정
	core 로 가는 경우 
		- LoggingConfig: 로깅 설정
		- GlobalExceptionHandler: 전역 예외 처리
		- CommonConstants: 프로젝트 전반에서 사용하는 상수들
		- EncryptionConfig: 암호화 관련 공통 설정

5. 그 외 
	feign : service 또는 (특정 API 모듈에서만 사용된다면) api 
	Redis  : 	캐싱 또는 비즈니스 로직과 관련(service), 또는 core
	JPA Config (Audit 등) : domain

 

참고 : 

https://www.youtube.com/watch?v=ipDzLJK-7Kc

https://www.youtube.com/watch?v=uvG-amw2u2s

https://www.youtube.com/watch?v=nH382BcycHc

https://techblog.woowahan.com/2637/

https://jojoldu.tistory.com/123

https://mangkyu.tistory.com/304

 

더보기

# 전체 빌드 (test 제외)

./gradlew build --stacktrace --info -x test

# 특정 모듈 빌드 # main 없는 경우 (common, domain, infra)

./gradlew :{project-name}-domain:build

# main 있는 경우 (api)

./gradlew :{project-name}-domain:bootJar

 

bootJar : dependecies와 클래스 파일을 모두 묶어서 빌드

jar : 클래스만 묶어서 빌드

 

 

 

'Spring' 카테고리의 다른 글

디버깅 모드  (0) 2025.01.19
FeignClient  (1) 2025.01.19
API(application programming interface), RestAPI  (0) 2023.05.22
웹 동작방식, HTTP, WAS, Web Server  (0) 2023.05.21
SOLID 원칙  (0) 2023.04.07