0. 서론
0.1 왜 이걸 찾아보게 되었는가?
- 멀티 모듈 아키텍처에서 의존성을 정리하면서 다양한 개념들이 나왔지만 필요한 것만 골라서 찾아봄
- 그 당시에는 어떤 역할을 하는지 간단하게 알아보고 사용했기에 잠시만 기억하고, 기억에 남아 있지 않음
- 하지만 계속 사용할거라고 생각했기 때문에 한번 정리가 필요하다고 생각
0.2 정리하고자 하는 내용
- gradle의 역할 및 특징
- build.gradle에서 볼 수 있는 설정들
- 의존성과 관련된 implementation, compileOnly, runtimeOnly, runtimeClasspath은 2편에서 다룰 예정
1. Gradle
1.1 Gradle 역할 및 특징
- 코드 컴파일 및 패키징
- Java, Kotlin, Groovy 등의 소스코드를 컴파일하고 JAR 또는 WAR 파일로 패키징
- 빌드 스크립트 기반 자동화
- build.gradle 파일을 이용해 빌드 과정(테스트, 배포 등)을 자동화
- 필요한 플러그인과 테스크 쉽게 추가 가능
- 테스트 자동화 지원
- Junit, TestNG 등의 테스트 프레임워크와 연동하여 자동화 테스트 실행
- 멀티 모듈 지원
- 의존성 관리
1.2 Gradle, Maven 비교
Gradle과 Maven의 차이점을 정리하면 다음과 같이 간단하게 정리할 수 있습니다.
증분 빌드
- 변경된 파일만 빌드하는 특징이 있기 때문에 불필요한 작업이 줄어듦
- 예를 들어 A.java, B.java가 있을 때 이 두 파일을 빌드한 후 A.java를 수정한 후 재빌드할 때 B.java는 다시 컴파일하지 않음
- Gradle을 사용하면 전체 빌드시간이 줄어들 수 있음. 반면 Maven은 무조건 전체 재빌드함
데몬 프로세스
- 백그라운드에서 실행되는 빌드 최적화 프로세스
- Gradle은 백그라운드에서 실행되는 데몬 프로세스를 사용해서 빌드 속도를 향상
- 데몬 프로세스는 Gradle을 실행할 때마다 새로 시작되지 않고, 이미 실행 중인 프로세스를 재사용해서 빌드 속도를 높임
병렬 빌드
- 멀티코어 CPU를 활용하여 여러 작업을 동시에 실행할 수 있음
- 병렬로 빌드하고 싶으면 아래와 같이 빌드할 때 parallel 옵션을 포함
./gradlew build --parallel
캐싱
- 이전에 빌드한 결과를 캐싱해서 동일한 작업을 실행하지 않도록 최적화
- 다운로드한 라이브러리를 캐싱하기 때문에 불필요한 통신 최소화
스크립트 문법
- Maven은 pom.xml 기반으로 설정
- Gradle은 Groovy/Kotlin DSL을 사용하여 상대적으로 Maven 보다 편리하게 관리
2. Gradle 구성 요소
2.1 Plugins
Plugin이란?
- Gradle 빌드 시스템의 기능을 확장하는 모듈
- Gradle이 기본적으로 제공하는 기능 외에도 특정 작업을 쉽게 사용할 수 있도록 도와주는 추가 기능
Plugins 예시
plugins {
id 'java'
id 'org.springframework.boot' version '3.1.0'
id 'io.spring.dependency-management' version '1.1.0'
}
- 위와 같이 자바와 스프링 부트 설정 플러그인을 추가하면 다음과 같은 기능을 사용할 수 있음
- Java plugin 예시 테스크: compileJava, test, jar 등
- Spring Boot 예시 테스크 : bootRun, bootJar
2.2 Configurations
configurations란?
- 새로운 의존성 그룹을 정의하거나 기존 설정을 확장할 때 사용
- 이를 통해 의존성을 조금 더 유연하게 관리할 수 있음
configurations 사용 예시
1. 새로운 Configuration 정의
- 아래와 같이 utilConfig라는 의존성 그룹을 정의해서 사용할 수 있음
configurations {
utilConfig
}
dependencies {
utilConfig 'org.apache.commons:commons-lang3:3.12.0'
}
2. 기존 Configuration 확장
- compileOnly 설정이 기존에 설정된 annotationProcessor를 상속
- 기본적으로 anntationProcessor와 compileOnly는 분리되어 있음
- Lombok을 사용한다고 했을 때 아래와 같이 사용할 수 있는데, 어노테이션 프로세서가 동작하지 않음
- 이유는 annotationProcessor가 compileOnly와 별개라서, compileOnly에서는 Lombok의 프로세서를 인식 못함
- 그렇기 때문에 compileOnly 설정이 annotationProcessor를 상속받아 문제를 해결할 수 있음
configurations {
compileOnly {
extendsFrom annotationProcessor
}
}
dependencies {
compileOnly 'org.projectlombok:lombok'
annotationProcessor 'org.projectlombok:lombok'
}
3. 특정 Configuration 제외
- 아래 예시와 같이 implementation Configuration slf4j 라이브러리를 사용하지 않도록 할 수 있음
configurations {
implementation {
exclude group: 'org.slf4j', module: 'slf4j-log4j12'
}
}
2.3 Repositories
repositories 역할
- repositories는 의존성을 어디서 다운로드할지 지정하는 역할을 함
- 즉 라이브러리를 가져올 저장소를 설정할 수 있음
repositories 사용 예시
- 가장 흔하게 사용할 수 있는 Maven Central 저장소로부터 라이브러리를 가져오는 mavenCentral()이 있음
- 사내에 Nexus 서버를 두고 Nexus로부터 라이브러리를 가져올 수도 있음
repositories {
//가지고오는 라이브러리 저장소 주소 -> https://repo1.maven.org/maven2/
mavenCentral()
}
repositories {
maven {
url "https://nexus.test.com/repository/test/"
}
}
2.4 dependencies
dependencies 역할
- 프로젝트에 필요한 의존성을 관리할 수 있는 설정
dependencies 사용 예시
- 아래와 같이 implementation, compileOnly, runtimeOnly 등등 다양한 의존성 설정을 통해 구성할 수 있음
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.mysql:mysql-connector-j'
annotationProcessor 'org.projectlombok:lombok'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
testRuntimeOnly 'org.junit.platform:junit-platform-launcher'
}
2.5 allprojects, subprojects
allprojects, subprojects의 역할
- 멀티모듈을 사용하고 있는 경우에 루프 프로젝트에서 하위 프로젝트를 설정할 수 있는 방법이다.
- allProjects는 루트 프로젝트와 하위 프로젝트에 모두 설정을 적용할 때 사용
- subProjects는 하위 프로젝트에만 설정을 적용할 때 사용
allprojects, subprojects 사용 예시
- api 모듈이 있고, 여기 하위 모듈로 공통적으로 DTO나 유틸 클래스를 관리하는 core 모듈, domain 코드를 관리하는 domain 모듈이 있다고 가정
- 모듈마다 라이브러리를 당겨서 사용하고 싶기 때문에 allProjects에서는 어떤 repositories를 사용할지 정할 수 있도록 구성
- subprojects에서는 lombok, apache common langs 라이브러리를 공통적으로 사용하도록 설정해 모든 모듈에서 lombok과 apache common langs 라이브러리를 이용 가능
allprojects {
repositories {
mavenCentral()
}
}
subprojects {
apply plugin: 'java'
apply plugin: 'io.spring.dependency-management'
dependencies {
compileOnly 'org.projectlombok:lombok'
annotationProcessor 'org.projectlombok:lombok'
testCompileOnly 'org.projectlombok:lombok'
testAnnotationProcessor 'org.projectlombok:lombok'
implementation 'org.apache.commons:commons-lang3:3.12.0'
}
}
2.6 project
project의 역할
- project는 각 모듈을 정의하고 설정하는 기본 단위
- 멀티모듈 프로젝트에서는 여러 개의 project가 존재하고, 이를 build.gradle에서 설정할 수 있음
project 사용 예시
- 멀티 모듈 아키텍처이고 크게 api 모듈, domain 모듈, core 모듈이 있다고 가정
- 각 api 모듈은 다음과 같은 역할을 가짐
- api와 서비스를 관리하는 모듈을 api 모듈
- 공통 DTO나 유틸 클래스를 관리하는 core 모듈
- domain 코드를 관리하는 domain 모듈
- 각 api 가 최상위 모듈이고 아래에 core 모듈과, domain 모듈을 의존하고 있다고 했을 때 project에서 다음과 같이 모듈을 구성할 있음
project(':main-api') {
dependencies {
implementation project(':core')
implementation project(':domain')
}
}
3. 글을 마치며
이번에는 build.gradle에서 코드 블럭을 가지고 있는 설정들에 대해 알아보았습니다. 다음 2편에서는 dependencies 설정에서 볼 수 있는 의존성 설정들에 대해 정리해 보겠습니다. 읽어주셔서 감사합니다.
'Spring' 카테고리의 다른 글
Gradle 설정 알아보기 (2편) (0) | 2025.02.23 |
---|---|
Flyway 도입 전 탐색해보기 (2) | 2024.12.07 |
환경변수가 있었는데요? 없었습니다 (2) | 2024.11.09 |
JPA 양방향 매핑 탈출기 (0) | 2024.10.27 |
@PathVariable 엔드포인트 매핑 원리 (1) | 2024.10.12 |