[Java] Gradle

Junkyu_Kang·2024년 6월 12일

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

  • 프로젝트에 대한 설정 정보를 작성하는 파일이다.
    멀티 모듈 프로젝트에서 하위 모듈을 추가하는 경우에는 setting 파일에 추가해주어야한다.
rootProject.name = 'SSAFY_Project'
include 'Module-API'
include 'Module-Domain'

build.gradle

  • gradle의 꽃.... 빌드 의존성 설정 파일이다.. 항상 의존성 오류 나면 가장 먼저 봐야할 곳

저장소
build.gradle은 외부 라이브러리를 사용할 수 있게 한다..

필요한 라이브러리를 자동으로 다운로드하고 통합한다.

저장소는 각종 프로그램이 저장되는 위치이다.

mavenCentral(), jcenter() 2개의 저장소가 있다.
통상 mavenCentral()을 쓰긴 하는듯?

repositories {
	mavenCentral()
    // jcenter()
}
  • implementation: 내부 의존성을 런타임에서만 보이는 구현 의존성
  • compileOnly: compile에만 필요하고, runtime에는 필요 없는 라이브러리
  • runtimeOnly: runtime에만 필요하고, compile에는 필요없는 라이브러리
  • annotationProcessor: 어노테이션 기반 라이브러리를 컴파일러가 인식하도록 함 (lombok, queryDSL)
  • testImplementation: 테스트에 사용하는 라이브러리

아래는 프로젝트 일부의 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을 써도 되지만 안써야될 이유가 없다.
빠르고 간단하고 관리하기 편하니까 말이다..

다들 편한 길로 가자 껄껄 레거시 멀리멀리~

profile
강준규

0개의 댓글