Spring

스프링 멀티모듈 나누기 개념 및 실습(메이븐, 그래들)

네이버 웹툰 인턴십 과제를 진행하다가 서비스가 커지면서 기존 프로젝트를 멀티모듈로 나눠서 개발하게 되었는데

개인적으로 서버 통신 관련해서 튜토리얼 당시 그래들을 통해서 간단한 멀티 모듈을 진행하였었는데 인턴 과정에서는 메이븐을 통해서 진행하게 되어 개념을 정리하고 그래들, 메이븐 실습을 진행하겠습니다.

메이븐 프로젝트 코드 주소 : https://github.com/whdals7337/maven-multi-module

그래들 프로젝트 코드 주소 : https://github.com/whdals7337/gradle-multi-module

멀티모듈이란?

멀티 모듈이란 개념은 한 프로젝트 안에 라이브러리처럼 사용 가능한 상태로 모듈들을 구성하고 그것들을 다른 모듈에서 가져다 쓸 수 있도록 만드는 것이라고 이해할 수 있습니다.

대부분의 서비스는 단일 프로젝트로 구성되는 일이 거의 없습니다.
아무리 작게 구성해도 일정 수준 이상의 트래픽을 감당하려면 사용자와의 접점을 담당하는 서버 DB와의 접점을 담당하는 서버로 구분하여 구성하게 됩니다.

 

이럴 경우 고민이 되는 것이 그럼 web과 api 모두에서 사용되는 클래스들은 어떻게 다룰 것인가?

1. 복사 & 붙여넣기 - 실수의 여지, 한쪽이 변경되면 다른쪽도 변경해줘야하는 중복 관리 포인트가 발생

2. 공통으로 사용하는 모듈을 jar로 만들고 이를 메이븐 원격 저장소에 deploy, 사용하는 모듈에서 디펜던시에 추가하여 사용 - 공통으로 사용하는 모듈이 변경될때마다 버전 변경, 메이븐 원격 저장소에 deploy

3. 멀티모듈 - 공통으로 사용하는 클래스를 모듈로 만들어서 가져다 쓰는 방식으로 중복 관리 포인트 발생하지 않음, 원격 저장소에 배포하지않아도 됨. 

 

인턴 당시 프로젝트가 커다란 프로젝트는 아니지만 역할(core, api, admin,consumer 등)이 분리되어야 된다고 생각하여 멀티모듈을 진행하였습니다.

 

멀티모듈을 진행하면서 제일 중요하다고 생각한 부분이 각 모듈에 무엇을 위치 시킬 것 인가였습니다.

(공통 DB 설정, api와 다른 모듈의 글로벌 예외처리 등 각 모듈마다 가지고 있어야하는 부분

kafka 등 특정 모듈에서만 사용하는 설정)

 

관련해서 우형 블로그에 좋은 글이 있어서 한번 읽어보시길 추천드립니다. https://techblog.woowahan.com/2637/

 

메이븐

1. 간단한 프로젝트 생성

2. 모듈 만들기

저는 CORE 모듈을 만들어 주겠습니다.

 

 

만들고 나면 multi의 pom.xml이 아래와 같을 텐대

packaging: pom, jar, war 등이 가능 한데 root의 경우 메이븐 package 될 때 자기 스스로 jar, war가 되는 것이 아닌 설정으로 셋팅 되어야 하기 때문에 pom으로 설정해줍니다. 차후 하위 모듈에서 package 진행시 multi의 설정이 합쳐지게 됩니다.

 

modules: 해당 프로젝트 하위에 있는 모듈로 차후 api 를 추가하고 보면 추가되어 있는것을 확인할 수 있습니다.

 

parent: 스프링부트 프로젝트로 스프링 프레임워크 부트를 부모로 셋팅해둡니다. multi를 부모로 두는 core의 경우도 스프링 프레임워크 부트 관련하여 사용할 수 있습니다. (스프링 프레임워크 부트 - multi - core 순)

 

groupid, artifact, version 의 경우 아래와 같이 하위 모듈에서 부모를 설정할 때 사용하게 됩니다.

(메이븐에 배포할 때 등에서도 해당 값을 사용한다. - 현 프로젝트는 메이븐에 배포안하긴함. ㅎ)

 

왼쪽 메이븐 탭의 의존성 부분을 보면 아래와 같이 multi에 설정한 의존성이  core에도 들어와 있는 것을 확인할 수 있는데 root의 pom의 설정의 하위 모듈 모두에서 사용된다고 보면 된다.

api모듈을 같은 방식으로 추가해준다.

 

이제 src는 필요없으니 지우고 api 모듈에 ApiApplication 클래스(스프링 부트 메인)을 추가해준다. 

3. core에 공통 클래스 만들고 api에서 사용하기

core 하위에 Member라는 클래스를 만들어 줍니다.

api 모듈에서 해당 객체를 사용할려면 core 모듈 의존성을 아래 처럼 추가해줍니다. 

추가해주면 아래와 같이 api 모듈에서 core의 객체를 사용할 수 있게 됩니다.

 

api 모듈의 ApiApplication을 통해서 실행 시키면 아래처럼 잘 나오는 것을 확인할 수 있습니다.

4. api package 진행

mvn package -pl api -am

메이븐 명령어로

pl : package 대상 모듈

am: 연결된 모듈을 같이 package 진행

 

실행해보면 아래처럼 되는데 이유는 core에는 스프링부트 메인 클래스가 없어서 인데 core는 혼자서 돌아가는 모듈이 아닌데 메인 클래스를 추가해야할까?

답은 아니다. 아래는 multi의 pom으로 빌드 설정이 기본적으로 들어가 있는 것을 확인 할 수 있는데 이 설정은 하위 모듈 전체에 들어가게되고 해당 빌드를 따라서 core를 빌드하려고 하기 때문에 문제가 발생한다.

이를 해결하는 방법으로 빌드 관련된 코드를 api쪽으로 이동 시키면 됩니다.

 

잘 따라오셨다면 발생하지 않겠지만 혹시 아래와 같은 문제가 발생한다면

빌드 설정이 core에 들어가 있지 않는지 확인하시고 없는데도 그렇다면

core와 api의 base dir을 동일하게 맞추고 스캔 범위를 설정해 주면 해결 될 것입니다.

5. jar 확인

api 모듈 하위 target에 아래처럼 jar 파일이 만들어지는데 해당 jar를 실행하여 확인하면 멀티 모듈 기본적인 셋팅이 되었습니다.

그래들

그래들의 경우 위의 메이븐과 다른 지점에 대해서만 설명드리겠습니다 .ㅎ

1. 프로잭트 생성

위에서 메이븐을 그래들로 변경하시면됩니다.

2. 모듈 생성

위에서 메이븐 모듈부분을 그래드 모듈로 변경해서 생성하시면 됩니다.

위의 설정이 메이븐에서는 pom.xml의 modules 부분입니다.

 

3. 그래드 설정

subprojects 부분이 하위 모듈에 적용될 내용으로

플러그인 적용

group, version, java version 설정

저장소 설정

롬복 설정

의존성 설정(여기에 적으면 모든 하위 모듈에 적용 됨)

 

core 그래들 설정으로

의존성(여기에서 설정하면 core에만 의존성이 추가됨)

bootjar 설정 (앞서 메이븐에서 core가 jar 파일로 package되는 부분이 기본값인 반면 그래들에서는 아래와 같이 설정해야함)

 

api 에서 core 설정

4. controller 설정 및 실행

Member는 메이븐에서 사용한 것과 동일한 것을 core모듈에 생성후 아래 처럼 controller를 작성하여 실행하면 정상 작동합니다.

 

5. jar 확인

그래들에서는 bootjar를 진행하면 알아서 연결된 모듈을 가져오기 때문에 아래와 같은 명령어를 사용하면 됩니다.

./gradlew api:bootJar

 

'Spring' 카테고리의 다른 글

트랜잭션 격리 수준  (0) 2021.05.30
Spring에서 사용하는 어노테이션 정리  (0) 2021.05.29
Spring 트랜잭션 전파  (0) 2021.05.29
springboot에서 redis 다루기  (0) 2021.05.23
Spring Interceptor  (0) 2021.04.12