카테고리 없음

[Spring] Gradle

JABHACK 2024. 12. 11. 21:11

Gradle

📌 Java와 유사한 문법 구조를 가진 Groovy기반의 스크립트 언어를 사용하며 다양한 소프트웨어를 빌드(Build)할 수 있는 유연한 빌드 자동화 도구이다.

  • 빌드란 소스 코드를 컴퓨터가 실행 가능한 파일로 변환해주는 작업이다.

빌드와 빌드 자동화 도구

 

 

[1]  Gradle 특징

  1. 유연성
    • 복잡한 빌드 시나리오를 처리할 수 있는 유연한 시스템을 제공한다.
    • 빌드 스크립트를 통해 다양한 빌드 작업을 정의하고, 필요한 경우 커스터마이징할 수 있다.
  2. 성능
    • Build Cache
      • 빌드 결과물을 캐싱하여 재사용한다.
      • 라이브러리 의존성을 캐싱하여 재사용한다.
    • 점진적 빌드
      • 마지막 빌드 호출 이후 변경된 부분만 빌드한다.
      • 변경되지 않은 부분은 캐시 결과를 검색해 재사용한다.
    • 데몬 프로세스
      • 다음 빌드 작업을 위해 백그라운드에서 대기하는 프로세스
      • 초기 빌드 이후부터는 빌드 실행 시 초기화 작업을 거치지 않는다.
  3. 멀티 프로젝트 빌드 지원
    • 공통으로 사용하는 클래스를 모듈로 만들어 독립적인 각 프로젝트에서 사용할 수 있도록 한다.
  4. 설정 주입 방식
    • 필요한 설정을 직접 프로젝트에 주입하는 방식이다.
    • 공통되는 정보는 묶어서 한번에 주입이 가능하다.
    • 프로젝트별로 설정을 다르게 주입할 수 있다.

 

[2]  Gradle과 다른 빌드 도구 비교

  Gradle Maven Ant
설정 방식 Groovy/Kotlin DSL XML XML
성능 빠름 (증분 빌드, 캐싱 지원) 비교적 느림 느림 (모든 작업을 매번 실행)
의존성 관리 지원 (Maven, Ivy 호환) 지원 (Maven Central) 제한적 (Ivy 필요)
확장성 매우 유연, 사용자 정의 플러그인 가능 제한적 매우 유연
주요 사용 사례 현대적 프로젝트, 멀티 플랫폼 지원 Java 프로젝트 중심 간단한 자동화 작업

 

[3]  주요 Gradle 명령어

gradle tasks 사용 가능한 모든 작업(task) 목록을 표시.
gradle build 프로젝트를 빌드(컴파일, 테스트, 패키징 등)합니다.
gradle clean 이전 빌드 결과를 삭제합니다.
gradle test 프로젝트의 테스트를 실행합니다.
gradle run 애플리케이션 실행 (특정 플러그인이 필요).
gradle dependencies 프로젝트의 의존성을 확인합니다.
gradle assemble 소스 코드를 컴파일하고 JAR 파일 또는 기타 배포 가능한 아티팩트를 생성합니다.

 

 

[4]  Gradle에서 의존성 관리

Gradle은 의존성 관리를 통해 프로젝트의 외부 라이브러리를 다운로드하고 관리합니다.
의존성은 dependencies 블록 안에서 정의하며, 저장소는 repositories 블록에서 설정합니다.

1. 의존성 추가

dependencies {
    implementation 'org.springframework.boot:spring-boot-starter-web' // 실행 시 필요한 라이브러리
    testImplementation 'org.junit.jupiter:junit-jupiter' // 테스트 용도 라이브러리
}

2. 저장소 설정

repositories {
    mavenCentral() // Maven Central Repository
    jcenter() // JCenter Repository
}

 

[5]  Gradle 멀티 프로젝트 설정

Gradle은 대규모 애플리케이션에서 멀티 프로젝트 빌드를 지원합니다.

  • 루트 프로젝트의 settings.gradle
rootProject.name = 'my-multi-project'
include 'module1', 'module2' // 하위 프로젝트 포함
  • 각 하위 프로젝트의 build.gradle
plugins {
    id 'java'
}

dependencies {
    implementation project(':module1') // 다른 모듈을 의존성으로 추가
}

 

 

[6]  Gradle의 장점

  1. 효율적인 빌드 속도:
    • Gradle의 증분 빌드 기능은 수정된 부분만 빌드하여 속도를 대폭 향상시킵니다.
  2. 유연한 설정:
    • Groovy 또는 Kotlin DSL을 사용하여 빌드 스크립트를 자유롭게 작성 가능하며, 복잡한 프로젝트도 쉽게 관리 가능합니다.
  3. 강력한 플러그인 시스템:
    • 수많은 플러그인이 제공되며, 사용자 정의 플러그인을 만들어 프로젝트에 통합할 수 있습니다.
  4. 확장성:
    • 다양한 언어 및 플랫폼 지원으로 다양한 종류의 애플리케이션 빌드 가능.
  5. 커뮤니티 및 문서화:
    • 활발한 커뮤니티와 풍부한 공식 문서로 개발자가 쉽게 문제를 해결할 수 있습니다.

 

[7]  Gradle의 주요 단점

초기 학습 곡선 Gradle은 유연성과 DSL(Groovy/Kotlin) 기반의 스크립트를 제공하지만, 설정이 복잡할 경우 학습 곡선이 가파릅니다.
느린 초기 빌드 증분 빌드나 빌드 캐시를 사용하지 않는 초기 빌드는 Maven보다 느리게 느껴질 수 있습니다.
모호한 에러 메시지 복잡한 빌드 스크립트에서 문제가 발생할 경우, 에러 메시지가 직관적이지 않거나 원인을 파악하기 어려운 경우가 있습니다.
DSL 의존성 Groovy 또는 Kotlin DSL을 학습해야 하며, 기존 XML 기반(Maven 등)에 익숙한 사용자에게는 진입 장벽이 될 수 있습니다.
플러그인 의존성 문제 플러그인의 호환성 문제가 발생하거나 최신 플러그인을 찾기 어려운 경우가 종종 있습니다.
의존성 관리 중복 가능성 프로젝트 구조가 복잡해질수록 의존성 충돌 문제가 발생할 가능성이 있으며, 이를 해결하기 위해 추가적인 설정이 필요합니다.
멀티 프로젝트 빌드 관리 어려움 멀티 프로젝트 설정이 유연한 대신 복잡한 빌드 환경에서는 디버깅 및 설정 관리가 까다로울 수 있습니다.
Maven보다 적은 레퍼런스 Maven에 비해 더 적은 사용자와 레퍼런스를 제공하므로, 특정 문제에 대한 해결 정보를 찾기 어려울 때가 있습니다.

 

 

build.gradle

📌 Groovy 기반 언어의 빌드 스크립트로 스크립트를 작성하면 소스 코드를 빌드하고, 라이브러리들의 의존성을 관리할 수 있다.

  • Gradle 프로젝트의 빌드 설정의존성 관리를 담당하는 핵심 구성 파일입니다. Groovy DSL을 사용하여 작성되며, Gradle 프로젝트의 다양한 동작을 정의
// 1. 플러그인 정의
plugins {
    id 'java' // Java 플러그인
    id 'org.springframework.boot' version '3.0.0' // Spring Boot 플러그인
}

// 2. 프로젝트 정보
group = 'com.example' // 그룹 ID
version = '1.0.0' // 버전 정보
sourceCompatibility = '17' // Java 버전

// 3. 저장소 설정
repositories {
    mavenCentral() // Maven Central 저장소
}

// 4. 의존성 관리
dependencies {
    implementation 'org.springframework.boot:spring-boot-starter-web' // Spring Boot Starter Web
    testImplementation 'org.springframework.boot:spring-boot-starter-test' // 테스트 의존성
}

// 5. 태스크 정의 (선택적)
tasks.withType(JavaCompile) {
    options.encoding = 'UTF-8' // UTF-8 인코딩 설정
}

[1]  주요 구성 요소

1. 플러그인

  • Gradle은 플러그인을 통해 프로젝트의 기능을 확장합니다.
plugins {
    id 'java' // Java 애플리케이션 빌드용
    id 'org.springframework.boot' version '3.0.0' // Spring Boot 프로젝트 설정용
    id 'io.spring.dependency-management' version '1.1.0' // Spring 의존성 관리
}

 

2. 프로젝트 정보

  • 프로젝트의 기본 정보와 Java 버전 등을 설정합니다.
group = 'com.example' // 조직명
version = '1.0.0' // 애플리케이션 버전
sourceCompatibility = '17' // Java 버전

 

3. 저장소

  • 외부 라이브러리를 가져오는 저장소를 지정합니다.
repositories {
    mavenCentral() // Maven Central Repository
    jcenter() // JCenter Repository (필요 시 추가)
}

 

4. 의존성

  • 프로젝트에서 사용하는 라이브러리와 의존성을 관리합니다.
  • 종류:
    • implementation: 애플리케이션 실행 시 사용.
    • testImplementation: 테스트 전용.
    • runtimeOnly: 런타임 전용.
    • compileOnly: 컴파일 시에만 필요.
dependencies {
    // JPA
    implementation 'org.springframework.boot:spring-boot-starter-data-jpa'

    // SECURITY
    implementation 'org.springframework.boot:spring-boot-starter-security'

    // WEB
    implementation 'org.springframework.boot:spring-boot-starter-web'

    // LOMBOK
    compileOnly 'org.projectlombok:lombok'
    annotationProcessor 'org.projectlombok:lombok'

    // MySQL
    runtimeOnly 'com.mysql:mysql-connector-j'

    // Validation
    implementation 'org.springframework.boot:spring-boot-starter-validation'

    // JWT
    compileOnly group: 'io.jsonwebtoken', name: 'jjwt-api', version: '0.11.5'
    runtimeOnly group: 'io.jsonwebtoken', name: 'jjwt-impl', version: '0.11.5'
    runtimeOnly group: 'io.jsonwebtoken', name: 'jjwt-jackson', version: '0.11.5'

    // DEV_TOOL
    developmentOnly 'org.springframework.boot:spring-boot-devtools'

    // TEST
    testRuntimeOnly 'com.h2database:h2'
    testCompileOnly 'org.projectlombok:lombok'
    testCompileOnly group: 'io.jsonwebtoken', name: 'jjwt-api', version: '0.11.5'
    testImplementation 'org.springframework.boot:spring-boot-starter-test'
    testImplementation 'org.springframework.security:spring-security-test'
}
  • 의존성 설정
    • 라이브러리를 추가하는 시점을 설정할 수 있다.
    • Implementation
      • 컴파일, 런타임 시점 모두에서 사용한다.
    • compileOnly
      • 컴파일할 때만 사용되고 런타임 때에는 사용하지 않는다.
    • runtimeOnly
      • 런타임 때만 사용한다.
    • testImplementation
      • 테스트할 때만 사용한다.

 

5. 태스크

  • Gradle 태스크를 추가하거나 수정할 수 있습니다.
tasks.withType(JavaCompile) {
    options.encoding = 'UTF-8' // UTF-8 인코딩 설정
}

task printHello {
    doLast {
        println 'Hello, Gradle!' // 사용자 정의 태스크
    }
}

 

 

 

Task

📌 빌드 과정에서 실행 가능한 작업 단위입니다. 예를 들어, 컴파일, 테스트, 패키징, 정리 등을 수행하는 작업입니다. Gradle에서는 기본 제공 태스크사용자 정의 태스크를 모두 사용할 수 있습니다.

[1]  태스크의 기본 구조

task <태스크 이름> {
    // 태스크 정의
    doLast {
        println '이 태스크는 실행 시 마지막에 실행됩니다.'
    }
}
  • doLast: 태스크의 마지막 작업을 정의합니다.
  • doFirst: 태스크의 첫 번째 작업을 정의합니다.

[2]  기본 제공 태스크

Gradle은 프로젝트의 전형적인 빌드 작업을 처리하기 위해 여러 기본 태스크를 제공합니다.

태스크 이름설명

build 전체 빌드 프로세스를 실행합니다.
clean 이전 빌드에서 생성된 파일(예: build 폴더)을 삭제합니다.
test 프로젝트의 테스트 코드를 실행합니다.
assemble 프로젝트를 컴파일하고 패키징합니다.
dependencies 프로젝트의 의존성 트리를 출력합니다.
tasks 프로젝트에서 사용 가능한 모든 태스크를 나열합니다.
bootRun (Spring Boot) Spring Boot 애플리케이션을 실행합니다.

[3]  사용자 정의 태스크

Gradle에서 사용자가 직접 태스크를 정의할 수 있습니다.

(1) 간단한 사용자 정의 태스크

task hello {
    doLast {
        println 'Hello, Gradle!'
    }
}

 

(2) 실행 순서 지정 (dependsOn)

task taskA {
    doLast {
        println 'Executing Task A'
    }
}

task taskB(dependsOn: taskA) {
    doLast {
        println 'Executing Task B'
    }
}
  • dependsOn: 지정된 태스크가 먼저 실행된 후 현재 태스크가 실행됩니다.
  • 실행 순서:
    1. taskA
    2. taskB

 

(3) 조건부 실행 (onlyIf)

task conditionalTask {
    doLast {
        println 'This task will run only if the condition is true.'
    }
    onlyIf {
        System.getProperty('runTask') == 'true'
    }
}
  • Gradle 실행 시 -DrunTask=true 옵션을 통해 태스크 실행 가능:
    bash
    코드 복사
    gradle conditionalTask -DrunTask=true
     

(4) 매개변수 전달 (project.property)

task printMessage {
    doLast {
        println "Message: ${project.property('message')}"
    }
}
  • Gradle 실행 시 매개변수를 전달:
gradle printMessage -Pmessage="Hello, Gradle!"

[4]  태스크 타입 활용

Gradle은 미리 정의된 태스크 타입을 제공합니다. 이들을 사용하면 더 복잡한 작업을 쉽게 설정할 수 있습니다.

(1) Copy 태스크: 파일 복사

task copyFiles(type: Copy) {
    from 'src/resources' // 복사할 디렉터리
    into 'build/output'  // 복사 대상 디렉터리
}

(2) Delete 태스크: 파일 삭제

task cleanTempFiles(type: Delete) {
    delete 'temp' // 삭제할 파일 또는 디렉터리
}

(3) Exec 태스크: 외부 명령 실행

task runScript(type: Exec) {
    commandLine 'sh', './script.sh' // 실행할 명령
}

[5]  다중 프로젝트 빌드에서의 태스크

Gradle은 **다중 프로젝트 빌드(Multi-Project Build)**를 지원합니다. 각 하위 프로젝트에서 정의된 태스크를 중앙 프로젝트에서 호출할 수 있습니다.

예시: 중앙 프로젝트에서 하위 프로젝트 태스크 실행

task buildAll {
    dependsOn ':subproject1:build', ':subproject2:build'
    doLast {
        println 'All subprojects are built!'
    }
}

[6]  Spring Boot 관련 태스크

Spring Boot 플러그인을 사용하면 추가적인 태스크가 제공됩니다.

bootRun Spring Boot 애플리케이션을 실행합니다.
bootJar 실행 가능한 JAR 파일을 생성합니다.
bootBuildImage Docker 컨테이너 이미지 생성(Spring Boot 2.3+).
gradle bootRun
gradle bootJar
gradle bootBuildImage​

 


[7]  Gradle 태스크 명령어

Gradle에서 태스크를 실행하거나 관리할 때 사용하는 주요 명령어:

명령어설명

gradle tasks 프로젝트에서 사용 가능한 모든 태스크를 나열합니다.
gradle <taskName> 특정 태스크를 실행합니다.
gradle <taskName> --dry-run 태스크 실행 시 어떤 작업이 수행될지 시뮬레이션만 보여줍니다.
gradle clean 이전 빌드 결과를 삭제합니다.
gradle build 전체 빌드 작업을 수행합니다.