Notice
Recent Posts
Recent Comments
Link
«   2025/03   »
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
Archives
Today
Total
관리 메뉴

개발자

[멀티모듈 지옥 탈출기] 멀티 모듈 파헤쳐보기-1(JPA,Gradel,SpringBoot) 본문

개발자/workflow 리팩토링 프로젝트(SpringBoot,JPA,MySQL)

[멀티모듈 지옥 탈출기] 멀티 모듈 파헤쳐보기-1(JPA,Gradel,SpringBoot)

GoGo개발 2023. 5. 19. 17:09

WF 프로젝트 진행중 아주 복잡한 미션을 하나 받았다(저 한줄이 이렇게 복잡할 줄이야?)

 

바로 모듈을 분리해 보라는 것

처음엔 저 한줄이 얼마나 큰 파장을 불러일으킬 줄 몰랐다ㅠㅠ

바로 검색해서 찾아보니 배민기술블로그에 대표적인 글이 있었다

 

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

 

멀티모듈 설계 이야기 with Spring, Gradle | 우아한형제들 기술블로그

{{item.name}} 멀티 모듈 설계 이야기 안녕하세요. 배달의민족 프론트 서버를 개발하고 있는 권용근입니다. 멀티 모듈의 개념을 처음알게 되었을 때부터 현재까지 겪었던 문제점들과 그것을 어떻게

techblog.woowahan.com

이글 인데 처음 이 글을 읽고나서

????????????????????????????????????????????????????????????????????????????????????

물음표 백만개 상태. 글을 다 읽고 나서 든 생각

그래서 멀티모듈이 뭔데?..????????

개념을 이해하는 것만으로도 매우 복잡해서 각종 블로그,유투브,챗GPT (챗 GPT 물어볼때마다 답변 바뀌는거 너무 화남)까지 닥치는 대로 뒤져봤지만

 

첫째날 내 상태 :

인도 형님의 유튜브까지 봤지만 여전히 벗어날 수 없는 물음표 지옥...

그렇게 이틀간의 삽질끝에 어느정도 설계가 잡히고 멘토님에게 간단하게 구조설계에 관한 피드백을 받고 3일만에 구조를 짤 수 있었다. 

 

그래서 멀티 모듈이 뭔데?

 

Java에서 모듈이란 패키지의 한 단계 위의 집합체이고, 독립적으로 배포될 수 있는 코드의 단위를 이야기한다. 멀티 모듈 프로젝트는 하나의 프로젝트를 여러 개의 작은 모듈로 나누어서 개발하고 관리하는 방식이다. 각각의 모듈은 독립적으로 개발 및 빌드 될 수 있고, 다른 모듈과 의존성을 가질 수도 있다. 

그럼 이런 것도 가능해진다 -> 한 프로젝트에서 특정 모듈은 자바/스프링 스택을, 다른 모듈은 코틀린/스프링 스택을 사용할 수도 있는것이다. 스프링 부트 버전도 모듈마다 달라질 수 있다.

 

그래서 멀티모듈은 왜 쓰는건데?

 

프로젝트를 모듈화 시키면 좋은건, 직관적으로 생각해봤을 때 공통으로 쓰는 코드를 모아놓을 수 있다는 것!

출처 - https://techblog.woowahan.com/2637/

예를 들어 이렇게 3가지의 프로젝트가 있다면, 이 프로젝트에 각각 동일한 Domain이 필요한데 그럼 3가지 어플리케이션을 복붙해서 개발해야 되는문제가 발생한다.  예를 들어 한 프로젝트에서 도메인변경시 다른 모든 프로젝트에서도 동일하게 변경해주지 않으면 에러가 발생할 수 있는데, 이를 변경할 때 copy & paste 반복 작업을 개발자가 하다보면 휴먼에러가 발생 할 수 밖에 없다. 사람이 하는 일이니 사람마다 코드가 달라질 수도 있고 실수가 발생하여 공통 코드를 일치시키지 못할 수 있다는 것이다.

출처 -  https://dkswnkk.tistory.com/691

이런 느낌이다! 그럼 user엔티티를 위해 각 서버마다 user도메인이 있어야 서비스 로직을 구성할 수 있다. 그래서 이렇게 중복된 부분들을 모듈화 시켜서 블럭 조립하듯 갖다쓸 수 있게 하기 위해 멀티 모듈 프로젝트로 만드는 것 같다. 멀티 모듈을 적용해서 프로젝트를 구성하면 아래와 같이 된다.

 

이렇게 되면 중심 도메인을 모듈로 분리하여 Domain 이 가져야할 구조와 규칙 등을 동일하게 보장해주는 메커니즘이 만들어진다.

 

하지만 이렇게 멀티모듈을 구성할 때는 많은 제약이 따르는데 이 문제들을 해결해 나가는 과정을 배민기술 블로그에 나와있으니 참고하면 좋을 것 같다.(사실 아직까지 완벽하게 이해를 못해서 설명을 못하는것...ㅎ 앞으로 더 공부해서 보완해나갈 예정)

 

 

자 그럼 멀티 모듈이 어떤 것인지는 알아봤으니 내가 진행하고 있는 프로젝트에 적용해서 구조를 바꿔볼 차례!

 

-현재 나의 프로젝트 구조 

최상위 디렉토리 하나에 모든 패키지가 들어 있는 구조이다. 루트 모듈로써 모든 코드를 가지고 있는 것!

entity 클래스를 제외한 controller,service,DTO,repository가 도메인별로 나누어진 패키지안에 모여있는 구조로, 도메인별로 나누어져 있긴 하지만 한곳에 모여있어 프로젝트 규모가 커지면 관리하기가 쉽지 않아 질 것 같다. 도메인별로 나누어져있는 것 외에는 추상화가 많이 부족한 상황! 

 

여기서 멀티 모듈로 구조를 바꾸게 되면

단순히 같은 코드를 모아서 쓸뿐 아니라 의존성 관리도 용이해진다(현재는 루트 모듈에 모든 의존성이 있는 상황이라 따로 따로 빌드,배포할 수 없고 전체가 한 몸으로 움직이고 있다)

 

그래서 이러한 구조의 코드들을 분리하여 계층 만들어 주는 작업이 필요하다! 바로 레이어 아키텍처 패턴으로 만들어 주기

 

레이어 아키텍처(계층형 아키텍처)? 그건 또 뭔데?

 

 

1. 컨트롤러단을 위한 모듈 - Presentaion layer

 : 사용자가 데이터를 전달하기 위해 화면에 정보를 표시하는 것을 주 관심사로 둔다. Presentation Layer 는 비즈니스 로  직이 어떻게 수행되는지 알 필요가 없다. 대표적인 구성요소는 View와 Controller가 있다.

 

2. 서비스(비즈니스 도메인)을 위한 모듈 - Business Layer

: 비즈니스 로직을 수행하는 것을 주 관심사로 둔다. 마찬가지로 화면에 데이터를 출력하는 방법이나 혹은 데이터를 어디서, 어떻게 가져오는지에 대한 내용은 알고있지 않다. 그저 Persistence Layer에서 데이터를 가져와 비즈니스 로직을 수행하고 그 결과를 Presentation Layer 로 전달하면 된다. 대표적인 구성요소는 Service와 Domain Model 등이 있다.

 

경우에 따라 아래처럼 Service와 Domain Model을 별개의 계층으로 나누거나, 아예 Domain Model을 Layered Architecture 와 별개의 것으로 분리하는 경우도 더러 있는 것 같다

 

3. 레포지토리(영속성 계층)을 위한 모듈 - Persistence Layer

: 어플리케이션의 영속성을 구현하기 위해, 데이터 출처와 그 데이터를 가져오고 다루는 것을 주 관심사로 둔다. 대표적인 구성요소는 Repository, DAO 등이 있다.

 

4. Databas Layer

: MySQL, MariaDB, PostgreSQL, MongoDB 등 데이터베이스가 위치한 계층을 의미한다.

 

사실 이렇게 나누어져 있지만 사람마다 구조화하는 게 다 달라서 절대적으로 따를 필요는 없을 것 같다! 나도 위의 구조와는 조금씩 다르게 설계했다. 흐름을 따라가면 되는 듯?

 

이를 바탕으로, 내가 짠 멀티 모듈의 구조

 

employee-api-module : Controller, Exception,Reuquest

-현재는 employee 서버만 있으므로 나중에 admin이나 batch 서버가 생긴다면 해당 api-module을 추가해주면 된다(이게 멀티모듈을 쓰는 유용성 중 하나), 이 모듈에서 모든 모듈의 의존성을 가지고 있기 때문에 어플리케이션을 실행하는 main메소드는 이 모듈에만 만들 예정이다.

 

domain-module : ServiceDto, Response, Service, Exception

 - api가 domian에 의존하기 때문에 request,response를 service에서도 사용하기 위해 DTO를 domain에 구성했다

 

: 처음에는 domain의 request로 하나의 dto가 각 레이어의 데이터를 이동시켰지만(controller->service) 이제 각 레이어마다 dto를 분리하였다. api->domain모듈로 넘어갈때 api의 dto가 domain의 dto로 변환을 마치고 이동된다.

 

data- module : Entity, Repository,Dto

- 원래는 Enums클래스도 있었지만 common module로 이동시켰다. data모듈은 엔티티와 repository 레이어이고

domain에서 data 모듈로 넘어올때도 각 레이어마다 dto를 만들어서 domain -> data 모듈로 넘어갈때 dto의 변환이 필요하다

 

jwt-module : Servie,Dto,Exception,Security,Config

- spring security와 jwt 인증을 위한 모듈이다. login 로직이 여기에서 이루어진다.

 

redis-module : Config

- redis 모듈이다. redis와 관련된 설정이 이루어진다.

 

아직 정확한 설계가 아니고 해보는 단계이기 때문에 추후 구조가 변경될 수 있다. 아직 이해가 부족해서 계속 진행해가며 수정할건 수정하고 보완해갈 예정이다.

 

구조 설계는 여기까지이고 이제 실제 프로젝트의 모듈을 나누는 것은 다음 포스팅에서 계속하겠다!

공부하면서 정리해놓은 내용들이므로 틀린개념이 아주아주 많을 수 있다! 뭔가 틀린 것 같다면 포스팅을 보는 분들이아닌 제가 잘못 작성한것입니다~!

 

참고 블로그

 

https://dkswnkk.tistory.com/691

https://awse2050.tistory.com/m/109

https://hudi.blog/why-use-multi-module/

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

https://velog.io/@jonghyun3668/%EC%8A%A4%ED%94%84%EB%A7%81-%EB%B6%80%ED%8A%B8-%EB%8B%A8%EC%9D%BC-%EB%AA%A8%EB%93%88-%EC%BD%94%EB%93%9C%EC%97%90-%EB%A9%80%ED%8B%B0-%EB%AA%A8%EB%93%88%EC%9D%84-%EC%A0%81%EC%9A%A9%ED%95%98%EC%97%AC-%ED%94%84%EB%A1%9C%EC%A0%9D%ED%8A%B8-%EA%B5%AC%EC%A1%B0-%EA%B0%9C%EC%84%A0%ED%95%98%EA%B8%B0