JDWA 技术文档
首页
  • 数据库
  • 前端开发
  • 后端开发
  • 开发工具
  • 虚拟化技术
  • KVM显卡直通
  • FPGA仿真固件
  • 项目实战
  • 踩坑记录
  • 开发心得
  • 软件工具
  • 学习资料
  • 开发环境
更新日志
关于我
Gitee
GitHub
首页
  • 数据库
  • 前端开发
  • 后端开发
  • 开发工具
  • 虚拟化技术
  • KVM显卡直通
  • FPGA仿真固件
  • 项目实战
  • 踩坑记录
  • 开发心得
  • 软件工具
  • 学习资料
  • 开发环境
更新日志
关于我
Gitee
GitHub
  • 数据库

    • 数据库教程
    • MySQL免安装版使用指南
    • MySQL性能优化实践
    • Redis入门与实践
    • MinIO快速部署指南
    • MinIO基础使用教程
  • 前端开发

    • 前端开发教程
    • Vue.js开发最佳实践
    • CSS常用技巧与解决方案
    • JavaScript实用技巧与编程模式
    • CSS Grid布局教程
  • 后端开发

    • 后端开发教程
    • Spring Boot实战指南
    • Node.js Express 框架开发实战指南
    • Python Flask 框架开发指南
  • 开发工具

    • 开发工具教程
    • Git 基础教程
    • Git工作流实践指南
    • VS Code 全面使用指南
    • VS Code必装插件推荐
    • Docker基础入门
    • IntelliJ IDEA 使用技巧
    • Eclipse配置与优化
    • Sublime Text 高级技巧
    • Vim 从入门到精通
    • Maven 详解
    • Gradle 入门与进阶
    • Webpack 配置指南
    • npm 与 yarn 使用技巧
    • Makefile 编写指南
    • Navicat 使用指南
    • MCP本地部署教程
  • 虚拟化技术

    • JDWA虚拟化技术专题
    • KVM虚拟机去虚拟化技术详解
  • KVM显卡直通

    • KVM显卡GPU直通教程
  • FPGA仿真固件

    • FPGA仿真固件开发指南
    • 基础-完整设备仿真定制固件开发指南
    • 中级-完整设备仿真定制固件开发指南
    • 高级-完整设备仿真定制固件开发指南

Gradle 入门与进阶

Tips

本教程全面介绍Gradle构建工具的使用方法,从基础配置到高级应用,适用于Gradle 7.0及更高版本。

1. Gradle简介

Gradle是一个开源的自动化构建工具,它结合了Ant和Maven的优点,提供了更灵活、更高效的构建方式。Gradle使用Groovy或Kotlin DSL作为构建脚本语言,支持增量构建,并具有出色的多项目构建能力。

1.1 Gradle的主要特点

  • 声明式构建:使用Groovy或Kotlin DSL声明式构建脚本
  • 高度可定制:灵活的API允许自定义构建逻辑
  • 增量构建:智能跳过已完成的任务,提高构建速度
  • 构建缓存:缓存构建结果,减少重复工作
  • 多项目支持:强大的多项目构建能力
  • 插件生态系统:丰富的插件扩展功能
  • 依赖管理:高级依赖管理功能

1.2 与其他构建工具的对比

特性GradleMavenAnt
构建语言Groovy/Kotlin DSLXMLXML
可扩展性很高中等很高
约定优于配置支持但可选强制不支持
依赖管理强大而灵活内置但固定需要扩展
构建性能很高(增量构建)中等低
学习曲线陡峭中等中等
生态系统快速增长成熟广泛成熟

2. 安装与配置

2.1 安装Gradle

Windows安装:

  1. 下载Gradle二进制包:Gradle官方下载
  2. 解压到指定目录,如C:\Program Files\Gradle
  3. 设置环境变量:
    • 新建GRADLE_HOME,值为Gradle安装目录
    • 将%GRADLE_HOME%\bin添加到PATH变量

macOS安装:

# 使用Homebrew
brew install gradle

# 验证安装
gradle -v

Linux安装:

# Ubuntu/Debian
sudo apt install gradle

# SDKMAN方式(推荐)
curl -s "https://get.sdkman.io" | bash
source "$HOME/.sdkman/bin/sdkman-init.sh"
sdk install gradle

# 验证安装
gradle -v

2.2 Gradle Wrapper

Gradle Wrapper是推荐的使用方式,它允许在没有安装Gradle的环境中运行构建:

# 生成Wrapper文件
gradle wrapper --gradle-version=7.6

# 使用Wrapper运行构建
./gradlew build    # Linux/macOS
gradlew.bat build  # Windows

Wrapper文件包括:

  • gradlew/gradlew.bat:启动脚本
  • gradle/wrapper/gradle-wrapper.jar:Wrapper JAR
  • gradle/wrapper/gradle-wrapper.properties:配置文件

2.3 IDE集成

IntelliJ IDEA:内置Gradle支持,导入Gradle项目时自动识别

Eclipse:安装Buildship插件(Eclipse Marketplace)

Visual Studio Code:安装Gradle插件

3. Gradle基本概念

3.1 项目和任务

Gradle构建的两个基本概念:

  • 项目(Project):代表要构建的软件
  • 任务(Task):项目构建过程中的原子操作

每个Gradle构建至少包含一个项目,每个项目包含一个或多个任务。

3.2 构建生命周期

Gradle构建生命周期分为三个阶段:

  1. 初始化阶段:确定参与构建的项目
  2. 配置阶段:解析构建脚本,创建任务图
  3. 执行阶段:根据任务依赖顺序执行任务

3.3 构建脚本文件

Gradle项目通常包含以下文件:

  • build.gradle(.kts):项目构建脚本
  • settings.gradle(.kts):多项目构建设置
  • gradle.properties:构建属性配置
  • buildSrc/:构建逻辑源代码目录

4. 构建脚本基础

4.1 Groovy DSL与Kotlin DSL

Gradle支持两种DSL编写构建脚本:

Groovy DSL (build.gradle):

plugins {
    id 'java'
}

group = 'com.jdwa'
version = '1.0.0'

repositories {
    mavenCentral()
}

dependencies {
    implementation 'org.springframework.boot:spring-boot-starter:2.7.0'
    testImplementation 'junit:junit:4.13.2'
}

Kotlin DSL (build.gradle.kts):

plugins {
    java
}

group = "com.jdwa"
version = "1.0.0"

repositories {
    mavenCentral()
}

dependencies {
    implementation("org.springframework.boot:spring-boot-starter:2.7.0")
    testImplementation("junit:junit:4.13.2")
}

4.2 项目属性

定义和使用项目属性:

// 在build.gradle.kts中
val projectVersion by extra("1.0.0")
val javaVersion = JavaVersion.VERSION_17

// 在gradle.properties中
org.gradle.caching=true
org.gradle.parallel=true
kotlin.code.style=official

访问属性:

println("Project version: ${project.extra["projectVersion"]}")
println("Java version: $javaVersion")
println("Parallel execution: ${project.findProperty("org.gradle.parallel")}")

4.3 settings.gradle文件

settings.gradle(.kts)定义多项目构建结构:

// settings.gradle.kts
rootProject.name = "jdwa-multi-project"
include("app", "core", "util")

// 自定义项目路径
project(":app").projectDir = file("applications/app")

5. 任务(Task)

5.1 任务定义

基本任务定义:

// Kotlin DSL
tasks.register("hello") {
    description = "Prints hello world"
    group = "Custom"
    
    doLast {
        println("Hello, World!")
    }
}
// Groovy DSL
task hello {
    description 'Prints hello world'
    group 'Custom'
    
    doLast {
        println "Hello, World!"
    }
}

5.2 任务类型

使用预定义的任务类型:

// Kotlin DSL
tasks.register<Copy>("copyDocs") {
    from("src/docs")
    into("build/docs")
    include("**/*.md", "**/*.txt")
    exclude("drafts/**")
}

tasks.register<Zip>("packageDocs") {
    archiveFileName.set("docs.zip")
    destinationDirectory.set(file("$buildDir/dist"))
    
    from("$buildDir/docs")
}

5.3 任务依赖

定义任务间的依赖关系:

// 方式1:依赖声明
tasks.register("taskA") {
    dependsOn("taskB", "taskC")
    doLast {
        println("Task A executed")
    }
}

// 方式2:创建时依赖
tasks.register("taskD") {
    doLast {
        println("Task D executed")
    }
}

tasks.named("taskA") {
    dependsOn(tasks.named("taskD"))
}

// 方式3:延迟依赖
tasks.register("taskE") {
    dependsOn(provider { tasks.filter { it.name.startsWith("prepare") } })
    doLast {
        println("Task E executed after all prepare tasks")
    }
}

5.4 任务排序

控制任务执行顺序(不是依赖关系):

// 确保taskA在taskB之前执行,即使没有依赖关系
tasks.named("taskA") {
    mustRunAfter("taskB")
}

// taskC应该在taskD之前执行,但不强制
tasks.named("taskC") {
    shouldRunAfter("taskD")
}

// 确定finalizer任务
tasks.named("taskE") {
    finalizedBy("cleanup")
}

6. 依赖管理

6.1 配置仓库

配置依赖仓库:

repositories {
    // Maven中央仓库
    mavenCentral()
    
    // JCenter仓库
    jcenter()
    
    // 谷歌仓库
    google()
    
    // 自定义Maven仓库
    maven {
        url = uri("https://maven.aliyun.com/repository/public")
        name = "Aliyun"
    }
    
    // 本地Maven仓库
    mavenLocal()
    
    // Ivy仓库
    ivy {
        url = uri("https://ivy.example.org")
    }
}

6.2 依赖配置

添加依赖:

dependencies {
    // 编译时依赖
    implementation("org.springframework:spring-core:5.3.20")
    
    // 仅API依赖
    api("org.apache.commons:commons-lang3:3.12.0")
    
    // 仅编译时依赖
    compileOnly("org.projectlombok:lombok:1.18.24")
    
    // 注解处理器
    annotationProcessor("org.projectlombok:lombok:1.18.24")
    
    // 测试依赖
    testImplementation("junit:junit:4.13.2")
    testRuntimeOnly("org.junit.platform:junit-platform-launcher")
    
    // 特定配置依赖
    "developmentOnly"("org.springframework.boot:spring-boot-devtools")
}

6.3 依赖版本管理

依赖约束:

dependencies {
    // 声明约束
    constraints {
        implementation("org.apache.logging.log4j:log4j-core") {
            version { strictly("2.17.1") }
            because("Security vulnerability in earlier versions")
        }
    }
    
    // 使用约束的依赖
    implementation("org.apache.logging.log4j:log4j-core")
}

版本目录:

// 在settings.gradle.kts中
dependencyResolutionManagement {
    versionCatalogs {
        create("libs") {
            version("spring", "5.3.20")
            version("junit", "5.8.2")
            
            library("spring-core", "org.springframework", "spring-core").versionRef("spring")
            library("spring-context", "org.springframework", "spring-context").versionRef("spring")
            library("junit-api", "org.junit.jupiter", "junit-jupiter-api").versionRef("junit")
            
            bundle("spring", listOf("spring-core", "spring-context"))
            bundle("testing", listOf("junit-api"))
        }
    }
}

// 在build.gradle.kts中使用
dependencies {
    implementation(libs.spring.core)
    implementation(libs.bundles.spring)
    testImplementation(libs.bundles.testing)
}

6.4 依赖解析冲突

处理依赖冲突:

configurations.all {
    // 解决策略:失败
    resolutionStrategy.failOnVersionConflict()
    
    // 或解决策略:强制使用特定版本
    resolutionStrategy.force(
        "org.slf4j:slf4j-api:1.7.36",
        "com.google.guava:guava:31.1-jre"
    )
    
    // 缓存动态版本的时间
    resolutionStrategy.cacheDynamicVersionsFor(10, "minutes")
    
    // 缓存变化模块的时间
    resolutionStrategy.cacheChangingModulesFor(4, "hours")
}

7. 插件系统

7.1 应用插件

应用核心插件:

plugins {
    java
    `java-library`
    application
    `maven-publish`
}

应用社区插件:

plugins {
    id("org.springframework.boot") version "2.7.0"
    id("io.spring.dependency-management") version "1.0.11.RELEASE"
    id("com.github.johnrengelman.shadow") version "7.1.2"
}

7.2 自定义任务插件

在构建脚本中创建简单插件:

// 定义插件
class GreetingPlugin : Plugin<Project> {
    override fun apply(project: Project) {
        // 添加扩展
        val extension = project.extensions.create<GreetingExtension>("greeting")
        
        // 创建任务
        project.tasks.register("hello") {
            description = "Prints a greeting message"
            group = "Custom"
            
            doLast {
                println("${extension.message ?: "Hello"}, ${extension.target ?: "World"}!")
            }
        }
    }
}

// 定义扩展
open class GreetingExtension {
    var message: String? = null
    var target: String? = null
}

// 应用插件
apply<GreetingPlugin>()

// 配置插件
configure<GreetingExtension> {
    message = "Hi"
    target = "Gradle"
}

7.3 发布自定义插件

在buildSrc目录或独立项目中创建插件:

// buildSrc/build.gradle.kts
plugins {
    `kotlin-dsl`
}

repositories {
    mavenCentral()
}

// buildSrc/src/main/kotlin/com.jdwa.gradle/JdwaPlugin.kt
package com.jdwa.gradle

import org.gradle.api.Plugin
import org.gradle.api.Project

class JdwaPlugin : Plugin<Project> {
    override fun apply(project: Project) {
        // 插件实现
    }
}

// 在主项目build.gradle.kts中应用
plugins {
    id("com.jdwa.gradle")
}

7.4 常用插件介绍

  1. Java插件:编译Java源代码、运行测试、创建JAR
  2. 应用插件:创建可执行的JVM应用
  3. Spring Boot插件:构建Spring Boot应用
  4. Shadow插件:创建包含所有依赖的fat JAR
  5. Kotlin插件:支持Kotlin语言
  6. Docker插件:构建Docker镜像
  7. JaCoCo插件:代码覆盖率报告

8. 多项目构建

8.1 创建多项目结构

rootProject/
├── settings.gradle.kts
├── build.gradle.kts
├── app/
│   └── build.gradle.kts
├── core/
│   └── build.gradle.kts
└── util/
    └── build.gradle.kts

settings.gradle.kts:

rootProject.name = "jdwa-multi-project"
include("app", "core", "util")

8.2 配置所有项目

根项目build.gradle.kts:

// 所有项目通用配置
allprojects {
    group = "com.jdwa"
    version = "1.0.0"
    
    repositories {
        mavenCentral()
    }
}

// 仅子项目配置
subprojects {
    apply(plugin = "java")
    
    java {
        sourceCompatibility = JavaVersion.VERSION_17
        targetCompatibility = JavaVersion.VERSION_17
    }
    
    tasks.withType<Test> {
        useJUnitPlatform()
    }
}

8.3 子项目依赖

core/build.gradle.kts:

plugins {
    `java-library`
}

dependencies {
    api("org.apache.commons:commons-lang3:3.12.0")
    implementation("com.google.guava:guava:31.1-jre")
}

app/build.gradle.kts:

plugins {
    application
}

application {
    mainClass.set("com.jdwa.app.Main")
}

dependencies {
    implementation(project(":core"))
    implementation(project(":util"))
}

8.4 组合构建

复合构建允许不同的Gradle项目一起构建:

settings.gradle.kts:

includeBuild("../other-project")

依赖替换:

dependencies {
    implementation("org.example:other-project:1.0.0")
}

9. 构建性能优化

9.1 开启并行构建

# gradle.properties
org.gradle.parallel=true

或命令行:

./gradlew build --parallel

9.2 构建缓存

# gradle.properties
org.gradle.caching=true

或命令行:

./gradlew build --build-cache

9.3 增量编译

Gradle默认支持增量编译,确保任务正确声明输入和输出:

tasks.register<ProcessResources>("processConfig") {
    // 声明输入文件
    from(file("src/config"))
    
    // 声明输出目录
    into("$buildDir/config")
    
    // 声明属性输入
    inputs.property("version", project.version)
    
    // 过滤文件内容
    filter { line -> line.replace("@VERSION@", "${project.version}") }
}

9.4 配置Gradle守护进程

# gradle.properties
org.gradle.daemon=true
org.gradle.jvmargs=-Xmx2g -XX:MaxMetaspaceSize=512m -XX:+HeapDumpOnOutOfMemoryError

10. 高级特性

10.1 Gradle测试套件

设置测试套件:

testing {
    suites {
        // 默认测试套件
        val test by getting(JvmTestSuite::class) {
            useJUnitJupiter()
        }
        
        // 集成测试套件
        val integrationTest by registering(JvmTestSuite::class) {
            dependencies {
                implementation(project())
                implementation("org.testcontainers:testcontainers")
            }
            
            targets {
                all {
                    testTask.configure {
                        shouldRunAfter(test)
                    }
                }
            }
        }
    }
}

tasks.named("check") {
    dependsOn(testing.suites.named("integrationTest"))
}

10.2 自定义Task类型

创建自定义任务类型:

// 定义任务类型
abstract class CountLinesTask : DefaultTask() {
    @get:InputFiles
    @get:PathSensitive(PathSensitivity.RELATIVE)
    abstract val sources: ConfigurableFileCollection
    
    @get:OutputFile
    abstract val outputFile: RegularFileProperty
    
    @TaskAction
    fun count() {
        val counts = mutableMapOf<String, Int>()
        
        sources.forEach { file ->
            if (file.isFile) {
                val extension = file.extension
                val lineCount = file.readLines().size
                counts[extension] = (counts[extension] ?: 0) + lineCount
            }
        }
        
        val output = counts.entries.joinToString("\n") { 
            "${it.key}: ${it.value} lines" 
        }
        outputFile.get().asFile.writeText(output)
    }
}

// 使用自定义任务类型
tasks.register<CountLinesTask>("countLines") {
    sources.from(fileTree("src/main").include("**/*.*"))
    outputFile.set(file("$buildDir/reports/line-count.txt"))
}

10.3 发布构件

发布Maven构件:

plugins {
    `maven-publish`
    signing
}

// 配置发布
publishing {
    publications {
        create<MavenPublication>("mavenJava") {
            from(components["java"])
            
            pom {
                name.set("JDWA Library")
                description.set("A sample library for demonstration")
                url.set("https://github.com/AAASS554/jdwa-library")
                
                licenses {
                    license {
                        name.set("The Apache License, Version 2.0")
                        url.set("http://www.apache.org/licenses/LICENSE-2.0.txt")
                    }
                }
                
                developers {
                    developer {
                        id.set("jdwa")
                        name.set("记得晚安")
                        email.set("1412800823@qq.com")
                    }
                }
                
                scm {
                    connection.set("scm:git:git://github.com/AAASS554/jdwa-library.git")
                    developerConnection.set("scm:git:ssh://github.com/AAASS554/jdwa-library.git")
                    url.set("https://github.com/AAASS554/jdwa-library")
                }
            }
        }
    }
    
    repositories {
        maven {
            name = "GitHubPackages"
            url = uri("https://maven.pkg.github.com/AAASS554/jdwa-library")
            credentials {
                username = System.getenv("GITHUB_ACTOR")
                password = System.getenv("GITHUB_TOKEN")
            }
        }
    }
}

// 签名配置
signing {
    sign(publishing.publications["mavenJava"])
}

10.4 自定义Gradle插件库

创建公司内部的插件库:

// settings.gradle.kts
pluginManagement {
    repositories {
        gradlePluginPortal()
        maven {
            url = uri("https://maven.company.com/plugins")
            credentials {
                username = providers.gradleProperty("companyRepoUser").orNull
                password = providers.gradleProperty("companyRepoPassword").orNull
            }
        }
    }
    
    plugins {
        id("com.company.java") version "1.0.0"
        id("com.company.quality") version "1.2.0"
    }
}

11. 最佳实践

11.1 项目结构

标准Java项目结构:

project/
├── build.gradle.kts
├── settings.gradle.kts
├── gradle.properties
├── gradle/
│   └── wrapper/
├── src/
│   ├── main/
│   │   ├── java/
│   │   ├── kotlin/
│   │   └── resources/
│   └── test/
│       ├── java/
│       ├── kotlin/
│       └── resources/
├── buildSrc/         # 构建逻辑
└── config/           # 项目配置

11.2 配置管理

分离配置逻辑:

project/
├── gradle/
│   ├── libs.versions.toml  # 依赖版本目录
│   ├── build-logic.gradle  # 构建逻辑
│   └── publishing.gradle   # 发布配置

build.gradle.kts:

// 应用共享配置
apply(from = "gradle/build-logic.gradle")
apply(from = "gradle/publishing.gradle")

11.3 持续集成配置

GitHub Actions配置:

# .github/workflows/gradle.yml
name: Gradle Build

on:
  push:
    branches: [ main ]
  pull_request:
    branches: [ main ]

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
    - uses: actions/checkout@v3
    
    - name: Set up JDK 17
      uses: actions/setup-java@v3
      with:
        java-version: '17'
        distribution: 'temurin'
        
    - name: Setup Gradle
      uses: gradle/gradle-build-action@v2
      with:
        gradle-version: wrapper
        
    - name: Build with Gradle
      run: ./gradlew build
      
    - name: Run tests
      run: ./gradlew test
      
    - name: Publish Test Report
      uses: mikepenz/action-junit-report@v3
      if: always()
      with:
        report_paths: '**/build/test-results/test/TEST-*.xml'

11.4 常见问题解决

  1. 依赖解析问题:

    # 查看依赖树
    ./gradlew app:dependencies
    
    # 查看依赖洞察
    ./gradlew app:dependencyInsight --dependency commons-io:commons-io
    
  2. 任务配置问题:

    # 使用--scan生成构建扫描报告
    ./gradlew build --scan
    
    # 使用--info查看详细日志
    ./gradlew build --info
    
  3. 性能问题:

    # 生成性能报告
    ./gradlew build --profile
    
    # 使用构建扫描分析性能
    ./gradlew build --scan
    

结语

Gradle是一个强大而灵活的构建工具,掌握它需要时间和实践。本教程涵盖了Gradle的基本用法到高级特性,帮助你更好地理解和使用Gradle。随着项目的增长和复杂性的提高,Gradle的优势会越来越明显,特别是在构建性能和可维护性方面。

Prev
Maven 详解
Next
Webpack 配置指南