먼저, Maven, Gradle이 무엇인가에 대해 알아보자
아 참! 그전에 빌드라는 걸 먼저 알아야 할 것 같다.
빌드란
- 소스코드 파일을 컴퓨터에서 실행할 수 있는 독립 소프트웨어 가공물로 변환하는 과정 또는 그에 대한 결과물이다.
쉽게 말하자면 우리가 작성한 소스코드(java), 프로젝트에서 쓰이는 각각의 파일 및 자원 등(.xml, .jar, .properties)을 JVM이나 톰캣같은 WAS가 인식할 수 있는 구조로 패키징하는 과정 및 결과물이라고 할 수 있다.
이러한 빌드를 할 수 있게 도와주는 것이 빌드 도구(Build tool) 이다.
빌드 도구는 프로젝트 생성, 테스트 빌드, 배포 등의 작업을 위한 전용 프로그램이다. 빠른 기간동안 계속 늘어나는 라이브러리 추가, 프로젝트를 진행하며 라이브러리의 버전 동기화의 어려움을 해소하고자 등장하게 됐다.
Maven과 Gradle은 프로젝트의 전체적인 라이프사이클을 관리해주며는 빌드 도구 인 것이다.
자 그럼 좀 더 자세히 살펴보도록 하자.
Maven이란 ?
아파치라는 회사에서 만든 자바용 프로젝트 관리 도구이다.
주로 라이브러리 의존성 관리를 위해 사용되며, 프로젝트에서 필요한 라이브러리들을 POM(Project Object
Model)에 정의해주면, Maven이 네트워크를 통해 자동으로 다운로드하여 프로젝트에 주입해 준다.
Maven Repository (mvnrepository.com/) 에서 원하는 의존성을 검색하여 밑의 소스 처럼 POM.xml에 넣어주면 된다.
...
<dependencies>
...
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId> <!-- mysql을 사용하기위해 -->
<version>6.0.6</version>
</dependency>
</dependencies>
장점으로는
- 뛰어난 의존성 관리(의존성 자동업데이트, 저장소를 통한 라이브러리 일괄 관리)
- 모든 프로젝트에 걸쳐 쉽게 적용 가능한 일관적인 사용 방법
- 간단한 설정을 통한 배포 관리
단점은
- pom.xml 파일 관리(pom.xml이 장황하게 길어질 수 있음)
- 프로젝트에 특화된 복잡한 빌드 기능 제약
- 네트워크 환경에서만 사용가능 (네트워크 환경에서만 pom.xml에 명시된 라이브러리를 다운로드 해주기 때문에 로컬환경에서는 라이브러리 사용을 위해서 별도의 라이브러리(.jar) 파일이 필요)
어찌 단점이 더 길게 느껴집니다.
저는 이제 Gradle로 갈아타겠습니다.
(둘다 사용하는 법을 익히도록 하겠습니다.)
Maven의 동작 과정
- Maven은 pom.xml 파일을 위에서 부터 아래로 순차적으로 읽는다.
- 이때, Maven은[groupId / artifactId / version ]을 기준으로 각각의 라이브러리를 구분 합니다.
- 구분한 라이브러리가 로컬 저장소에 있는지 확인합니다. 보통은 USER_HOME/.m2/repository에 저장됩니다.
- 로컬 저장소에 동일한 라이브러리가 존재할 경우, 원격 저장소로부터 해당 라이브러리를 다운받지 않습니다.
- 로컬 저장소에 동일한 라이브러리가 존재하지 않을 경우, 원격 저장소로 부터 필요한 jar 파일을 다운받아 로컬 저장소에 복사합니다.
자 그럼 Gradle에 대해 알아 봅시다.
Gradle이란?
마찬가지로 JVM기반의 빌드 도구입니다. 구글이 만든 Android Studio(앱 개발 IDE)에서 기본적인 빌드 시스템으로 사용됩니다.
Gradle의 특징
- 오픈소스 기반의 빌드 자동화 시스템으로 Groovy 기반 DSL(Domain-Specific Language)로 작성
- Build-by-convention을 바탕으로 한다. 따라서 스크립트 규모가 작고 읽기 쉬움
- Multi 프로젝트 빌드를 지원하기 위해 설계됐다.
- 설정 주입 방식(Configuration Injection)
그래서 Maven과 Gradle의 차이점은 무엇인가..? 왜 사람들은 Maven에서 Gradle로 바꾸는 것일까..?
Gradle이 Maven보다 좋은점
- Build라는 동적인 요소를 XML로 정의하기에는 어려운 부분이 많다.
- 설정 내용이 길어지고 가독성 떨어짐
- 의존관계가 복잡한 프로젝트 설정하기에 부적절
- 상속구조를 이용한 멀티 모듈 구현
- 특정 설정을 소수의 모듈에서 공유하기 위해서는 부모 프로젝트를 생성하여 상속하게 해야 함 (상속의 단점 생김)
- Gradle은 Groovy를 사용하기 때문에, 동적인 빌드는 Groovy 스크립트로 플러그인을 호출하거나 직접 코드를 짜면 된다.
- Configuration Injection 방식을 사용해서 공통 모듈을 상속해서 사용하는 단점을 커버했다.
- 설정 주입 시 프로젝트의 조건을 체크할 수 있어서 프로젝트별로 주입되는 설정을 다르게 할 수 있다.
스프링부트를 이용하여 같은 기능과 라이브러리 의존성을 가지는 Maven, Gradle 프로젝트를 생성해 보았다.
- 스크립트 길이와 가독성 면에서 Gradle(groovy)이 앞선다.
- 빌드와 테스트 실행 결과 Gradle이 더 빠르다. (Gradle이 캐시를 사용하기 때문에 테스트 반복 시 차이가 더 커진다.)
- 의존성이 늘어날 수록 성능과 스크립트 품질의 차이가 심해질 것이다.
Maven
<?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>
<groupId>com.example</groupId>
<artifactId>demo-maven</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>demo-maven</name>
<description>Demo project for Spring Boot</description>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.4.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</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>
</plugin>
</plugins>
</build>
</project>
Gradle
buildscript {
ext {
springBootVersion = '1.5.4.RELEASE'
}
repositories {
mavenCentral()
}
dependencies {
classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}")
}
}
apply plugin: 'java'
apply plugin: 'idea'
apply plugin: 'org.springframework.boot'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = 1.8
repositories {
mavenCentral()
}
dependencies {
compile('org.springframework.boot:spring-boot-starter')
testCompile('org.springframework.boot:spring-boot-starter-test')
}
위의 두개의 빌드 도구를 비교해보면 가독성 면에서는 일단 확실히 Gradle이 보기가 편한 것 같다.
참조
'JAVA SPRING' 카테고리의 다른 글
@Transactional (0) | 2021.06.03 |
---|---|
Spring WebFlux란? (0) | 2021.05.29 |
Spring Version( 스프링 버전 별 특징, 차이) (2) | 2021.05.25 |
예외처리하기 (@ControllerAdvice) (0) | 2021.05.06 |
스프링 Component Scan (0) | 2021.04.12 |