안녕하세요. 이번 포스팅에서는 메이븐으로 멀티 모듈 프로젝트를 구성하는 방법에 대해 알아보겠습니다.
먼저 Maven
과 Multi Module
이 무엇인지 알아보고, 그 후에 인텔리제이 IDE 를 사용하여 프로젝트를 구성해보겠습니다.
Apache Maven
우리는 소스 코드를 작성하고 코드를 실행하기 위해 JAR 나 WAR 등의 파일을 만든다.
이처럼 소스 코드 파일 및 리소스를 컴퓨터에서 실행 가능한 산출물(Artifact)로 만드는 일련의 과정을 Build 라고 한다.
빌드는 전처리, 컴파일, 패키징, 테스팅, 배포 등의 여러 과정으로 이루어지지만
개발자들은 Maven 과 같은 Build Tool 을 사용하여 한 번의 클릭으로 실행 파일을 얻을 수 있다.
Project Object Model (POM)
메이븐은 POM 을 통해 프로젝트를 설명하고 종속성을 관리한다. 또한 멀티 모듈 프로젝트의 모듈 간 관계를 정의한다.
POM 은 루트 디렉토리에 pom.xml 파일로 생성된다. 일반적인 pom.xml 의 구조를 살펴보자.
<project>
<modelVersion>4.0.0</modelVersion>
<groupId>com.una</groupId> // 프로젝트를 생성한 회사 또는 그룹의 고유한 기본 이름
<artifactId>una</artifactId> // 프로젝트의 고유한 이름
<packaging>jar</packaging> // 패키징 방법 (e.g. war, jar, zip ...)
<version>1.0-SNAPSHOT</version>
<name>com.una</name>
<properties> // 사용자가 지정하는 속성
<spring.version>5.3.16</spring.version>
</properties>
<dependencies> // 프로젝트에서 사용하는 라이브러리 관리
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
<version>5.8.2</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>${spring.version}</version>
</dependency>
</dependencies>
<build>
<plugins> // 빌드에 사용하는 플러그인 관리
<plugin>
//...
</plugin>
</plugins>
</build>
</project>
- groupId: 프로젝트를 생성한 회사 또는 그룹의 고유한 기본 이름
- artifactId: 프로젝트의 고유한 이름
- packaging: 패키징 방법 (e.g. war, jar, zip ...)
- properties: pom.xml 파일 내에서 ${name} 표기법을 사용해서 변수처럼 사용할 수 있다.
- 버전을 변경할 때 properties 내에 있는 숫자만 변경하면 해당 속성을 사용하는 모든 종속성이 업데이트되기 때문에 편리하다.
- dependency: 프로젝트와 의존 관계에 있는 라이브러리 관리 (종속성 관리)
- Maven 은 중앙 리포지토리에서 해당 라이브러리를 자동으로 다운로드하기 때문에 로컬에 저장하지 않아도 된다.
- 외부 라이브러리에 대한 종속성을 선언하기 위해서는 groupId, artifactId, version 을 명시해야한다.
Maven 의 장점과 단점
장점
- 프로젝트의 종속성을 파일 하나로 관리할 수 있다.
- 중앙 리포지토리에서 라이브러리를 다운로드하기 때문에 스토리지 사용량이 적다.
단점
- 메이븐을 통해 라이브러리를 다운받기 위해서는 메이븐을 설치해야한다.
- Maven Wrapper 를 통해 메이븐을 설치하지 않고 사용하는 방법이 있다.
Multi Module
모듈은 독립적으로 운영될 수 있는 구성요소의 단위다. 예로는 우리가 pom.xml 에 명시하는 외부 라이브러리들이 있다.
그렇다면 하나의 프로젝트를 멀티 모듈로 구성하는 이유가 무엇일까?
그 이유에는 여러 가지가 있을 것이다.
FrontEnd, BackEnd 를 한 번에 빌드하기 위해
여러 프로젝트에서 동일한 도메인을 사용하기 위해
여러 프로젝트에서 동일한 버전의 라이브러리를 사용하기 위해
결국 멀티 모듈을 구성하면 하나의 비즈니스를 여러 프로젝트로 역할과 책임을 나누어 관리하기 용이해진다.
실습 프로젝트 구성
이번 실습에서는 종속성을 루트 프로젝트에서 관리하기 위해 멀티 모듈을 구성해보도록 하겠다.
루트 프로젝트는 모든 프로젝트에서 공통적으로 사용하는 라이브러리들을 관리하는 용도로 사용한다.
먼저 루트 프로젝트를 maven 으로 생성한다.
다음과 같이 루트 프로젝트가 생성되었다.
루트 프로젝트는 pom 의 역할을 하기 때문에 패키징을 pom 으로 추가한다.
그리고 spring-boot-starter-parent 를 선언한다.
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<packaging>pom</packaging>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.7.2</version>
</parent>
<groupId>org.example</groupId>
<artifactId>parent-project</artifactId>
<version>1.0-SNAPSHOT</version>
</project>
spring-boot-starter-parent 는 부모인 spring-boot-dependencies 를 살펴보면 다음과 같다.
스프링 부트를 사용하면서 필요한 여러 dependency 들이 선언되어 있다.
spring-boot-starter-parent 를 사용하는 이유는 다음과 같다.
- 개발자가 직접 dependency 를 하나하나 추가하지 않아도 된다.
- 사용하는 스프링 버전에 맞는 dependency 들의 버전 관리가 편리하다.
이제 Spring Boot 자식 모듈을 생성해보자.
Dependency 는 Spring Web 만 추가해주었다.
동일하게 하나의 자식 모듈을 더 생성했다. 이제 프로젝트 구조는 다음과 같다.
parent-project 밑에 core, service 모듈을 생성했다.
루트 프로젝트의 pom.xml 에 자식 모듈을 추가한다.
<modules>
<module>core</module>
<module>service</module>
</modules>
자식 모듈의 pom.xml 을 보면 parent 로 spring-boot-starter-parent 를 바라보고 있을 것이다.
<!-- 변경 전 -->
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.0.0</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
다음과 같이 변경하여 루트 프로젝트를 바라보도록 하자.
<parent>
<groupId>org.example</groupId>
<artifactId>parent-project</artifactId>
<version>1.0-SNAPSHOT</version>
</parent>
이제 자식 모듈에서 종속성을 관리해보자. pom.xml 에 라이브러리를 추가한다.
자식 모듈에서 다른 버전을 사용해야 한다면 버전을 명시하여 재정의할 수 있다.
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
</dependency>
</dependencies>
터미널을 열어서 세 개의 모듈을 한 번에 빌드해보자. 루트 프로젝트 디렉토리에서 다음 명령어를 입력한다.
mvn package
모든 모듈이 한 번에 빌드 된 것을 확인할 수 있다.
마치며
이번 포스팅에서는 메이븐을 통해 멀티 모듈을 구성해보았습니다.
더 복잡한 멀티 모듈 프로젝트에는 Gradle 을 사용하면 최적화할 수 있으나 아직까지는 루트 프로젝트가 종속성 관리의 역할만 하고 있기 때문에, 그리고 이후 문제 발생 시 빌드 툴의 변경이 어렵지 않다고 하여 사용이 익숙한 Maven 으로 구성하였습니다.
Reference
- Baeldung, Multi-Module Project with Maven
- Maven 멀티 모듈 구성방법
- 우아한형제들 기술블로그, 멀티모듈 설계 이야기 with Spring, Gradle
'Spring Boot' 카테고리의 다른 글
[Spring Boot] Tomcat 알아보기 (1) Servlet 과 Servlet Container (0) | 2023.01.17 |
---|---|
[Spring Boot] DTO 는 왜, 언제 사용할까? (2) | 2023.01.03 |
[Spring Boot] AWS S3 이미지파일 업로드하기 (0) | 2022.09.03 |
[Spring Boot] Mockito 로 테스트 하기 (0) | 2022.08.06 |
Spring Security 인가 처리 - AccessDecisionManager, AccessDecisionVoter (0) | 2022.08.04 |