
우리는 스프링에서 초기에 프로젝트를 생성할 때, 빌드 선택 도구를 Maven으로 선택할지, Gradle로 선택할지에 대한 결정이 필요합니다.

이 두 빌드 관리 도구에는 어떤 차이점이 있고, 어떤 상황에서 어떤 도구를 선택해야 하는 지 궁금해서 조사를 해보았습니다. 🤔
우선 Maven과 Gradle은 모두 빌드 관리 도구입니다.
직역하면, 빌드를 관리하는 도구라고 하는데.. 그렇다면 빌드란 무엇일까요?
빌드란, 소스코드 파일을 컴퓨터에서 실행할 수 있는 독립적인 형태로 변환하는 과정과 결과를 말한다.
즉, 우리가 작성한 java 코드와 프로젝트에서 쓰인 각각의 파일 및 자원(xml, properties, jar)들을 JVM이나 WAS가 인식할 수 있도록 패키징하는 과정 및 결과물을 의미합니다.
그렇다면 빌드 관리 도구란 무엇일까요?
빌드를 관리해주는 도구이겠죠?
빌드 관리 도구란, 소스 코드에서 애플리케이션을 생성하면서 여러가지 외부 라이브러리를 사용하는데, 빌드 관리 도구는 사용자가 직접 관리할 필요 없이 필요한 라이브러리들을 자동으로 관리해주는 도구이다.
빌드 관리 도구는 다음과 같은 작업을 수행한다고 합니다.
대표적인 도구로는 Ant, Maven, Gradle 등이 있습니다.
우리는 그 중에서 자주 선택의 기로에 놓이게 되는 Maven과 Gradle에 대해서 알아봅시다.

Maven이란, 자바 전용 프로젝트 Lifecycle 관리 목적 빌드 도구이며, Apache의Ant의 불편함을 해결하고자 만들어졌다.
Maven 에서는 미리 정의하고 있는 빌드 순서가 있으며 이 순서를 Lifecycle이라고 합니다. Lifecycle의 가 빌드 단계를 Phase라고 하는데, 이런 Phase들은 의존관계를 가지고 있습니다.
Clean : 이전 빌드에서 생성된 파일들을 삭제하는 단계
Validate : 프로젝트가 올바른지 확인학고 필요한 모든 정보를 사용할 수 있는 지 확인하는 단계
Compile : 프로젝트의 소스코드를 컴파일하는 단계
Test : 유닛(단위) 테스트를 수행하는 단계(테스트 실패시 빌드 실패로 처리, 스킵 가능)
Package : 실제 컴파일된 소스 코드와 리소스들을 jar등의 배포를 위한 패키지로 만드는 단계
Verify : 통합테스트 결과에 대한 검사를 실행하여 품질 기준을 충족하는지 확인하는 단계
Install : 패키지를 로컬 저장소에 설치하는 단계
Site : 프로젝트 문서를 생성하는 단계
Deploy : 만들어진 Package를 원격 저장소에 release하는 단계
각 단계를 모두 수행하는 것이 아니라 원하는 단계까지만 수행할 수도 있으며, test단계는 큰 프로젝트의 경우에 몇시간이 소요될 수 있으니 수행하지 않도록 스킵이 가능합니다.
Maven은 필요한 라이브러리를 pom.xml에 정의합니다. 이를 프로젝트 모델링이라고도 합니다.
POM이란 뭘까요?
POM은 Project Object Model의 약자로, 프로젝트 정보(프로젝트 이름, 라이센스, 빌드 설정(소스, 리소스, Lifecycle 별 실행한 plugin 등 빌드 관련 설정), 빌드 환경(사용자 환경 별로 달라질 수 있는 프로필 정보, pom 연관 정보(의존 프로젝트, 모듈, 상위 프로젝트 등)을 담고 있다.
그럼 이제 Gradle에 대해서도 알아볼까요?

Maven을 대체할 수 있는 프로젝트 구성 관리 및 범용 빌드 툴이며, Ant Builder와 Groovy script를 기반으로 구축되어 기존 Ant의 역할과 배포 스크립의 기능을 모두 사용 가능하며, 스프링부터와 안드로이드에서 사용된다.
추가적으로 빌드 속도가 Maven에 비해 10~100배 가량 빠르며, Java, C/C++, Python 등을 지원한다고 합니다.
좋은 가독성 : 코딩에 의한 간결한 정의가 가능하므로 가독성이 좋다.
용이한 재사용 : 설정 주입 방식(Configuration Injection)을 사용하므로 재사용에 용이하다.
구조적인 장점 : Build Script를 Groovy 기반의 DSL(Domail Specific Language)를 사용하여 코드로서 설정 정보를 구성하므로 구조적인 장점이 있다.
멀티 프로젝트 : Gradle은 멀티 프로젝트 빌드를 지원하기 위해 설계된 빌드 관리 도구이다.
그렇다면 Maven과 Gradle 중에 어떤 도구가 더 좋다고 할 수 있을까요?

일단 스크립트를 비교하기 위해 같은 기능을 담은 프로젝트를 직접 만들어 보았습니다.
<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.2.2</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.example</groupId>
<artifactId>my-restful-service</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>my-restful-service</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>17</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<excludes>
<exclude>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</exclude>
</excludes>
</configuration>
</plugin>
</plugins>
</build>
</project>
plugins {
id 'java'
id 'org.springframework.boot' version '3.2.2'
id 'io.spring.dependency-management' version '1.1.4'
}
group = 'com.example'
version = '0.0.1-SNAPSHOT'
java {
sourceCompatibility = '17'
}
configurations {
compileOnly {
extendsFrom annotationProcessor
}
}
repositories {
mavenCentral()
}
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
implementation 'org.springframework.boot:spring-boot-starter-web'
compileOnly 'org.projectlombok:lombok'
developmentOnly 'org.springframework.boot:spring-boot-devtools'
runtimeOnly 'com.h2database:h2'
annotationProcessor 'org.projectlombok:lombok'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
}
tasks.named('test') {
useJUnitPlatform()
}
우선 한 눈에 봐도 스크립트의 길이와 가독성 면에서 Gradle이 우세해 보입니다.
그리고 빌드와 테스트 실행 결과 Gradle이 더 빠른 것을 확인할 수 있었습니다.
그 이유는 Gradle은 캐시를 사용하기 때문이라고 합니다.
이렇게 되면, 의존성이 늘어날 수록 성능과 스크립트의 품질 차이가 심해지겠죠?
아래 사진은 Maven과 Gradle의 속도 차이를 그래프로 나타낸 것입니다. 사진에 대한 출처는 본문 하단에 남겨두겠습니다.




차이점을 정리하자면,
Maven은 프로젝트가 커질수록 빌드 스크립트의 내용이 길어지고 가독성이 떨어집니다.
반면에 Gradle은 훨씬 적은 양의 스크립트로 짧고 간결하게 작성할 수 있습니다.
Maven이 정적인 형태의 XML 기반으로 작성되어 동적인 빌드를 적용할 경우 어려움이 많지만, Gradle은 Groovy를 사용하기 때문에 동적인 빌드는 Groovy 스크립트로 플러그인을 호출하거나 직접 코드를 짜면 된다는 장점이 있습니다.
그리고 Maven의 경우 멀티 프로젝트에서 특정 설정을 다른 모듈에서 사용하려면 상속을 받아야 하지만, Gradle은 설정 주입 방식을 사용하기 때문에 멀티 프로젝트에 매우 적합합니다.
과거에는 Maven을 많이 사용했었지만 요즘은 Gradle로 많이 넘어오는 추세라고 합니다.
만약 둘 중 하나를 선택해야 하는 상황이라면, 많은 사람들이 Gradle을 추천할 것 같습니다.
이렇게 빌드 관리 도구부터 Maven과 Gradle의 차이점까지 알아보았습니다.
저는 이제 스프링을 막 배우고 있는 시점이라 주로 Gradle을 이용하고 있는데, 언젠가는 Maven도 써보면서 그 차이점을 몸소 느낄 수 있는 날이 오겠죠? 🙂
읽어주셔서 감사합니다.
Reference
Maven과 Gradle의 개념 및 비교
Maven과 Gradle 속도 비교