1학기에 사용했던 Maven구조는 pom.xml 파일로 의존성을 관리했다.
물론 외부 라이브러리를 관리할 수 있었고, Ant와 달리 장황한 빌드 스크립트 문제를 해결하여 보기 쉽게 만들어졌다.
라이프 사이클 개념이 도입되어 Build 순서를 정할 수 있었지만 XML 자체에 한계가 있었다.
김영한 자바 강의를 들은 사람이라면 Gradle을 사용하는 법을 배웠을텐데 Gradle은 상대적으로 많은 장점을 가졌다.

Gradle 장점
1. 외부 라이브러리 관리 용이(라이프사이클 포함)
2. 유연한 빌드 스크립트 작성 가능
3. Groovy 문법을 사용한다
가장 큰 장점은 바로 성능이다.
점진적 빌드와 캐싱을 통해 빠른 빌드 속도를 자랑한다.
점진적 빌드 - 이미 빌드된 파일을 제외한 변경된 내용만 빌드 하는 것
캐싱 - 캐싱을 하기 때문에 다른 빌드 도구에 비해 속도가 빠르다.
데몬 프로세스 - 서비스 요청에 응답하기 위한 프로세스로 메모리 상에 빌드 결과물을 오래 보관하는 역할을 한다.(다음 빌드 시간 단축)

출처: gradle.org
기존 Maven의 pom.xml 구조
<project ... 생략 ...>
<modelVersion>4.0.0</modelVersion>
<groupId>그룹 ID</groupId>
<artifactId>아티팩트 ID</artifactId>
<version>버전</version>
<packaging>jar</packaging>
<name>이름</name>
<properties>
...
속성 정보
...
</properties>
<dependencies>
...
의존 라이브러리 정보
...
</dependencies>
</project>
Gradle의 Build.gradle 구조
plugins {
id 'java'
id 'org.springframework.boot' version '2.7.11'
id 'io.spring.dependency-management' version '1.0.15.RELEASE'
}
group = 'hello'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = '11'
configurations {
compileOnly {
extendsFrom annotationProcessor
}
}
repositories {
mavenCentral()
}
dependencies {
...
}
tasks.named('test') {
useJUnitPlatform()
}
Gradle Project 구조
├── build.gradle
├── .gradle
├── gradle
│ └── wrapper
│ ├── gradle-wrapper.jar
│ └── gradle-wrapper.properties
├── gradlew
├── gradlew.bat
├── settings.gradle
gradlew, gradlew.bat
gradle-wrapper 실행 명령어인데 윈도우 유저라면 .bat을 쓰면 된다. gradle을 설치않아도 빌드된다.
$ ./gradlew [Task]
$ gradlew [Task]
settings.gradle
rootProject.name = 'SSAFY_Project'
include 'Module-API'
include 'Module-Domain'
build.gradle
저장소
build.gradle은 외부 라이브러리를 사용할 수 있게 한다..
필요한 라이브러리를 자동으로 다운로드하고 통합한다.
저장소는 각종 프로그램이 저장되는 위치이다.
mavenCentral(), jcenter() 2개의 저장소가 있다.
통상 mavenCentral()을 쓰긴 하는듯?
repositories {
mavenCentral()
// jcenter()
}
아래는 프로젝트 일부의 build.gradle의 내용이다.
buildscript {
ext {
queryDslVersion = "5.0.0"
}
}
plugins {
id 'java'
id 'org.springframework.boot' version '3.2.3'
id 'io.spring.dependency-management' version '1.1.4'
}
group = 'org.lemon'
version = '1.0-SNAPSHOT'
java {
sourceCompatibility = '17'
}
configurations {
compileOnly {
extendsFrom annotationProcessor
}
}
repositories {
mavenCentral()
}
dependencies {
// Test
testImplementation platform('org.junit:junit-bom:5.9.1')
testImplementation 'org.junit.jupiter:junit-jupiter'
// JPA
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
// Spring MVC
implementation 'org.springframework.boot:spring-boot-starter-web'
// Validation
implementation 'org.springframework.boot:spring-boot-starter-validation'
// WebSocket
implementation 'org.springframework.boot:spring-boot-starter-websocket'
// lombok
compileOnly 'org.projectlombok:lombok'
annotationProcessor 'org.projectlombok:lombok'
// DataBase
runtimeOnly 'com.h2database:h2'
runtimeOnly 'com.mysql:mysql-connector-j'
// Test
testImplementation 'org.springframework.boot:spring-boot-starter-test'
testImplementation 'org.springframework.boot:spring-boot-starter-data-jpa'
// Mockito
testImplementation 'org.mockito:mockito-core:5.11.0'
// QueryDsl
implementation 'com.querydsl:querydsl-jpa:5.0.0:jakarta'
annotationProcessor "com.querydsl:querydsl-apt:${dependencyManagement.importedProperties['querydsl.version']}:jakarta"
annotationProcessor "jakarta.annotation:jakarta.annotation-api"
annotationProcessor "jakarta.persistence:jakarta.persistence-api"
// Swagger
implementation 'org.springdoc:springdoc-openapi-starter-webmvc-ui:2.0.2'
// 스프링 앱 서버의 상태를 확인
implementation 'org.springframework.boot:spring-boot-starter-actuator'
// JWT
implementation 'io.jsonwebtoken:jjwt-api:0.11.5'
implementation 'io.jsonwebtoken:jjwt-impl:0.11.5'
implementation 'io.jsonwebtoken:jjwt-jackson:0.11.5'
// redis
implementation 'org.springframework.boot:spring-boot-starter-data-redis'
//webClient
implementation 'org.springframework.boot:spring-boot-starter-webflux'
//Configuring the Annotation Processor
annotationProcessor "org.springframework.boot:spring-boot-configuration-processor"
// Spring Security
implementation 'org.springframework.boot:spring-boot-starter-security'
implementation "org.springframework.boot:spring-boot-starter-oauth2-client"
//bad World filter
implementation 'io.github.vaneproject:badwordfiltering:1.0.0'
implementation 'org.springframework.boot:spring-boot-starter-jdbc'
// S3
implementation 'org.springframework.cloud:spring-cloud-starter-aws:2.2.6.RELEASE'
// Firebase
implementation 'com.google.firebase:firebase-admin:9.2.0'
implementation group: 'com.squareup.okhttp3', name: 'okhttp', version: '4.10.0'
implementation 'com.google.firebase:firebase-admin:7.3.0'
// aop
implementation 'org.springframework:spring-aop:6.1.6'
// Bucket4J
implementation 'com.github.vladimir-bukhtoyarov:bucket4j-core:7.5.0'
// Prometheus
implementation 'io.micrometer:micrometer-registry-prometheus'
}
tasks.named('test') {
useJUnitPlatform()
}
def generated = 'src/main/generated'
tasks.withType(JavaCompile) {
options.compilerArgs += ["-parameters"]
options.getGeneratedSourceOutputDirectory().set(file(generated))
}
clean {
delete file(generated)
}
tasks.named('test') {
useJUnitPlatform()
}
항상 외부 라이브러리를 사용할 때 설정 정보에 대한 내용이 추가적으로 필요하다면 config의 대한 설정 정보도 미리 공부해둘 필요가 있다. ex swagger || FCM || redis 등
뭐 gradle을 안쓰고 maven을 써도 되지만 안써야될 이유가 없다.
빠르고 간단하고 관리하기 편하니까 말이다..
다들 편한 길로 가자 껄껄 레거시 멀리멀리~