Gradle全网最细学习手册(上篇)

🚀 Gradle 全网最细学习手册(上篇)

💡 现代构建工具:掌握Gradle核心概念、DSL语法、任务系统,体验比Maven更快更灵活的构建体验!

📖 学习导航

  • 🎯 适合人群:Java开发者、想学习现代构建工具的开发者、从Maven迁移的团队
  • ⏱️ 学习时长:建议3-4天完成上篇内容
  • 🎓 学习目标:掌握Gradle核心概念、熟练编写构建脚本、理解任务系统和依赖管理
  • 📚 学习方式:理论+实践,每个知识点都有详细示例和对比

📚 系列文章导航

  • 📖 上篇:基础概念 + DSL语法 + 任务系统 + 依赖管理
  • 📖 下篇:多项目构建 + 插件开发 + 性能优化 + 实战案例

📌 第一阶段:Gradle 基础概念与环境搭建

🎯 1. Gradle 是什么?深度解析

1.1 Gradle 的核心优势

Gradle是一个开源的构建自动化工具,专注于灵活性和性能。它结合了Ant的强大功能和Maven的依赖管理概念。

🔧 五大核心优势:

  1. 高性能:增量构建、构建缓存、并行执行
  2. 灵活性:基于Groovy/Kotlin DSL的强大脚本能力
  3. 可扩展性:丰富的插件生态系统
  4. 多语言支持:Java、Kotlin、Scala、C++、Python等
  5. 企业级特性:构建扫描、依赖洞察、性能分析
1.2 Gradle vs. Maven vs. Ant 详细对比
特性GradleMavenAnt
配置语言Groovy/Kotlin DSLXMLXML
构建性能🥇 最快(增量构建+缓存)🥉 较慢🥈 中等
灵活性🥇 极高(编程式配置)🥉 较低(约定优于配置)🥈 高(过程式)
学习曲线🥈 中等偏陡🥇 相对简单🥉 复杂
依赖管理🥇 强大且灵活🥈 强大但固化🥉 需手动管理
多项目支持🥇 原生支持🥈 通过聚合🥉 需手动配置
IDE支持🥇 优秀🥇 优秀🥈 一般
生态系统🥈 快速发展🥇 最成熟🥉 逐渐衰落
企业采用🥈 快速增长🥇 最广泛🥉 逐渐减少
1.3 Gradle 的核心概念

🎯 项目(Project)

  • 每个构建都包含一个或多个项目
  • 项目代表可以构建的组件(如JAR库、Web应用等)
  • 由build.gradle文件定义

🎯 任务(Task)

  • 构建的基本工作单元
  • 如编译代码、运行测试、创建JAR等
  • 任务之间可以有依赖关系

🎯 插件(Plugin)

  • 扩展Gradle功能的模块
  • 提供任务、约定和配置
  • 如Java插件、Spring Boot插件等

🎯 构建脚本(Build Script)

  • 使用Groovy或Kotlin DSL编写
  • 定义项目配置、依赖、任务等
  • 具有强大的编程能力

🛠️ 2. Gradle 安装与配置详解

2.1 安装方式对比

方式1:使用Gradle Wrapper(推荐)

# 优势:
# - 确保团队使用相同版本
# - 无需预安装Gradle
# - 自动下载指定版本

# 使用方式
./gradlew build    # Linux/Mac
gradlew.bat build  # Windows

方式2:手动安装

# 1. 下载Gradle
# 访问:https://gradle.org/releases/
# 下载:gradle-8.4-bin.zip

# 2. 解压并配置环境变量
export GRADLE_HOME=/opt/gradle/gradle-8.4
export PATH=$PATH:$GRADLE_HOME/bin

# 3. 验证安装
gradle --version

方式3:包管理器安装

# macOS (Homebrew)
brew install gradle

# Ubuntu/Debian
sudo apt install gradle

# Windows (Chocolatey)
choco install gradle

# Windows (Scoop)
scoop install gradle
2.2 Gradle Wrapper 详解

🔧 生成Wrapper

# 生成wrapper文件
gradle wrapper --gradle-version 8.4

# 生成的文件结构
project/
├── gradle/
│   └── wrapper/
│       ├── gradle-wrapper.jar
│       └── gradle-wrapper.properties
├── gradlew          # Unix脚本
├── gradlew.bat      # Windows脚本
└── build.gradle

📝 gradle-wrapper.properties配置

# Gradle Wrapper配置文件
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.4-bin.zip
networkTimeout=10000
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists

🚀 Wrapper优化配置

# 使用国内镜像加速下载
distributionUrl=https\://mirrors.cloud.tencent.com/gradle/gradle-8.4-bin.zip

# 或使用阿里云镜像
distributionUrl=https\://mirrors.aliyun.com/macports/distfiles/gradle/gradle-8.4-bin.zip

# 高级配置选项
networkTimeout=10000                    # 网络超时时间(毫秒)
validateDistributionUrl=true            # 验证下载URL
zipStoreBase=GRADLE_USER_HOME           # ZIP存储基础目录
zipStorePath=wrapper/dists              # ZIP存储路径

💡 Wrapper配置实战案例

# 案例1:企业内网环境配置
# 问题:公司内网无法访问外网,需要使用内部镜像
# 解决方案:
distributionUrl=https\://nexus.company.com/repository/gradle-distributions/gradle-8.4-bin.zip

# 案例2:开发团队版本统一
# 问题:团队成员使用不同Gradle版本导致构建不一致
# 解决方案:强制使用项目指定版本
./gradlew wrapper --gradle-version 8.4 --distribution-type bin

# 案例3:CI/CD环境优化
# 问题:CI环境每次都重新下载Gradle,浪费时间
# 解决方案:使用缓存友好的配置
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
# 在CI脚本中缓存 ~/.gradle 目录
2.3 Gradle 配置优化

📁 gradle.properties(项目级配置)详解

# ==================== 构建性能优化 ====================
# 启用Gradle守护进程(推荐)
org.gradle.daemon=true
# 说明:守护进程可以避免JVM启动开销,显著提升构建速度
# 适用场景:开发环境必开,CI环境可选

# 启用并行构建(推荐)
org.gradle.parallel=true
# 说明:允许多个项目并行构建,充分利用多核CPU
# 适用场景:多模块项目效果明显

# 按需配置(谨慎使用)
org.gradle.configureondemand=true
# 说明:只配置需要的项目,减少配置时间
# 注意:可能导致某些插件工作异常,需要测试

# 启用构建缓存(强烈推荐)
org.gradle.caching=true
# 说明:缓存任务输出,避免重复执行
# 效果:可以将构建时间减少50-90%

# ==================== JVM参数优化 ====================
# 基础JVM参数
org.gradle.jvmargs=-Xmx4g -XX:MaxMetaspaceSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8

# 详细JVM参数说明:
# -Xmx4g                           # 最大堆内存4GB
# -XX:MaxMetaspaceSize=512m        # 元空间最大512MB
# -XX:+HeapDumpOnOutOfMemoryError  # OOM时生成堆转储
# -Dfile.encoding=UTF-8            # 文件编码UTF-8

# 高级JVM优化(大型项目)
# org.gradle.jvmargs=-Xmx8g -XX:MaxMetaspaceSize=1g -XX:+UseG1GC -XX:+UseStringDeduplication

# ==================== 网络和代理设置 ====================
# 编码设置
systemProp.file.encoding=UTF-8

# HTTP代理设置
systemProp.http.proxyHost=proxy.company.com
systemProp.http.proxyPort=8080
systemProp.http.proxyUser=username
systemProp.http.proxyPassword=password

# HTTPS代理设置
systemProp.https.proxyHost=proxy.company.com
systemProp.https.proxyPort=8080
systemProp.https.proxyUser=username
systemProp.https.proxyPassword=password

# 非代理主机(多个用|分隔)
systemProp.http.nonProxyHosts=localhost|127.0.0.1|*.company.com

# ==================== 构建行为控制 ====================
# 控制台输出模式
org.gradle.console=rich
# 可选值:auto, plain, rich, verbose

# 日志级别
org.gradle.logging.level=lifecycle
# 可选值:quiet, warn, lifecycle, info, debug

# 警告模式
org.gradle.warning.mode=all
# 可选值:all, fail, summary, none

# ==================== 项目特定配置 ====================
# 应用版本
version=1.0.0-SNAPSHOT

# 自定义属性
app.name=MyApplication
app.description=My Gradle Application
app.mainClass=com.example.Application

# 数据库配置(开发环境)
db.url=jdbc:mysql://localhost:3306/myapp
db.username=dev_user
db.password=dev_password

# 构建配置
build.timestamp=${new Date().format('yyyy-MM-dd HH:mm:ss')}

🏠 ~/.gradle/gradle.properties(全局配置)详解

# ==================== 全局性能设置 ====================
# 全局JVM设置(适用于所有项目)
org.gradle.jvmargs=-Xmx8g -XX:MaxMetaspaceSize=1g -XX:+UseG1GC

# 全局并行构建
org.gradle.parallel=true

# 全局构建缓存
org.gradle.caching=true

# 全局守护进程设置
org.gradle.daemon=true

# ==================== 全局网络设置 ====================
# 全局代理设置(适用于所有项目)
systemProp.http.proxyHost=proxy.company.com
systemProp.http.proxyPort=8080
systemProp.https.proxyHost=proxy.company.com
systemProp.https.proxyPort=8080

# ==================== 认证信息 ====================
# Gradle Wrapper认证(私有仓库)
systemProp.gradle.wrapperUser=username
systemProp.gradle.wrapperPassword=password

# 仓库认证信息
nexusUsername=your_username
nexusPassword=your_password

# 签名密钥信息
signing.keyId=12345678
signing.password=your_signing_password
signing.secretKeyRingFile=/Users/username/.gnupg/secring.gpg

# ==================== 开发者个人设置 ====================
# 开发者信息
developer.name=John Doe
developer.email=john.doe@company.com
developer.organization=My Company

# 个人偏好设置
org.gradle.console=rich
org.gradle.warning.mode=all

💡 全局配置实战案例

案例1:企业开发环境统一配置

# ~/.gradle/gradle.properties
# 企业统一JVM设置
org.gradle.jvmargs=-Xmx6g -XX:MaxMetaspaceSize=512m -XX:+UseG1GC

# 企业代理设置
systemProp.http.proxyHost=proxy.company.com
systemProp.http.proxyPort=8080
systemProp.https.proxyHost=proxy.company.com
systemProp.https.proxyPort=8080
systemProp.http.nonProxyHosts=*.company.com|localhost

# 企业仓库认证
nexusUsername=${env.NEXUS_USERNAME}
nexusPassword=${env.NEXUS_PASSWORD}

# 开发者信息
developer.name=${env.USER}
developer.email=${env.USER}@company.com

案例2:个人开发机优化配置

# ~/.gradle/gradle.properties
# 个人机器性能优化(16GB内存)
org.gradle.jvmargs=-Xmx8g -XX:MaxMetaspaceSize=1g -XX:+UseG1GC -XX:+UseStringDeduplication

# 最大化并行度
org.gradle.parallel=true
org.gradle.workers.max=8

# 启用所有缓存
org.gradle.caching=true
org.gradle.configuration-cache=true

# 详细输出(开发调试用)
org.gradle.console=verbose
org.gradle.logging.level=info

案例3:CI/CD环境配置

# ~/.gradle/gradle.properties (CI环境)
# CI环境JVM设置
org.gradle.jvmargs=-Xmx4g -XX:MaxMetaspaceSize=512m

# CI环境优化
org.gradle.daemon=false          # CI环境不使用守护进程
org.gradle.parallel=true         # 启用并行构建
org.gradle.caching=true          # 启用构建缓存

# CI环境日志设置
org.gradle.console=plain         # 纯文本输出
org.gradle.logging.level=info    # 详细日志

# 构建行为
org.gradle.warning.mode=fail     # 警告时失败

📁 3. Gradle 项目结构深度解析

3.1 标准项目结构
my-gradle-project/
├── build.gradle(.kts)         # 构建脚本
├── settings.gradle(.kts)      # 设置脚本
├── gradle.properties          # 项目属性
├── gradlew                    # Wrapper脚本(Unix)
├── gradlew.bat               # Wrapper脚本(Windows)
├── gradle/
│   └── wrapper/
│       ├── gradle-wrapper.jar
│       └── gradle-wrapper.properties
├── src/
│   ├── main/
│   │   ├── java/             # Java源代码
│   │   ├── kotlin/           # Kotlin源代码
│   │   ├── resources/        # 资源文件
│   │   └── webapp/           # Web资源(Web项目)
│   ├── test/
│   │   ├── java/             # 测试代码
│   │   ├── kotlin/           # Kotlin测试代码
│   │   └── resources/        # 测试资源
│   └── integrationTest/      # 集成测试(可选)
├── build/                    # 构建输出目录
│   ├── classes/
│   ├── libs/
│   ├── reports/
│   └── tmp/
└── README.md
3.2 核心文件详解

📋 build.gradle 基础结构

// 插件配置
plugins {
    id 'java'
    id 'application'
    id 'org.springframework.boot' version '2.7.0'
}

// 项目基本信息
group = 'com.example'
version = '1.0.0'
sourceCompatibility = '11'

// 仓库配置
repositories {
    mavenCentral()
    gradlePluginPortal()
}

// 依赖配置
dependencies {
    implementation 'org.springframework.boot:spring-boot-starter-web'
    testImplementation 'org.junit.jupiter:junit-jupiter'
}

// 任务配置
tasks.named('test') {
    useJUnitPlatform()
}

// 应用配置
application {
    mainClass = 'com.example.Application'
}

⚙️ settings.gradle 配置

// 根项目名称
rootProject.name = 'my-gradle-project'

// 包含子项目
include 'subproject1', 'subproject2'

// 插件管理
pluginManagement {
    repositories {
        gradlePluginPortal()
        mavenCentral()
    }
}

// 依赖解析管理
dependencyResolutionManagement {
    repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
    repositories {
        mavenCentral()
    }
}
3.3 创建Gradle项目

方法1:使用Gradle init(推荐)

# 创建Java应用项目
gradle init --type java-application --dsl groovy --test-framework junit-jupiter

# 创建Java库项目
gradle init --type java-library --dsl kotlin --test-framework spock

# 创建Spring Boot项目
gradle init --type java-application --dsl groovy
# 然后手动添加Spring Boot插件

# 交互式创建
gradle init

方法2:手动创建

# 创建项目目录
mkdir my-gradle-project && cd my-gradle-project

# 创建标准目录结构
mkdir -p src/main/java/com/example
mkdir -p src/main/resources
mkdir -p src/test/java/com/example
mkdir -p src/test/resources

# 创建构建脚本
touch build.gradle
touch settings.gradle
touch gradle.properties

# 生成Wrapper
gradle wrapper --gradle-version 8.4

📝 最小化build.gradle示例

plugins {
    id 'java'
}

repositories {
    mavenCentral()
}

dependencies {
    testImplementation 'org.junit.jupiter:junit-jupiter:5.9.2'
}

tasks.named('test') {
    useJUnitPlatform()
}

📌 第二阶段:Gradle DSL 语法与构建脚本

📝 4. Groovy DSL 深度解析

4.1 Groovy DSL 基础语法

🎯 基本语法特性

// 1. 方法调用可以省略括号
println 'Hello Gradle'
println('Hello Gradle')  // 等价

// 2. 字符串插值
def version = '1.0.0'
println "Current version: ${version}"
println "Current version: $version"  // 简化形式

// 3. 闭包(Closure)
def myClosure = { param ->
    println "Parameter: $param"
}
myClosure('test')

// 4. 集合操作
def list = ['java', 'kotlin', 'scala']
list.each { language ->
    println "Language: $language"
}

// 5. Map操作
def config = [
    version: '1.0.0',
    encoding: 'UTF-8'
]
println config.version

🔧 Gradle DSL 核心概念

// 1. 配置块(Configuration Block)
android {
    compileSdkVersion 33
    defaultConfig {
        applicationId "com.example.app"
        minSdkVersion 21
    }
}

// 2. 任务配置
task myTask {
    doLast {
        println 'Executing myTask'
    }
}

// 3. 依赖配置
dependencies {
    implementation 'org.springframework:spring-core:5.3.21'
    testImplementation 'junit:junit:4.13.2'
}

// 4. 属性访问
project.version = '1.0.0'
version = '1.0.0'  // 简化形式
4.2 构建脚本结构详解

📋 完整的build.gradle结构

// ==================== 1. 插件配置 ====================
plugins {
    // 核心插件
    id 'java'
    id 'application'

    // 社区插件
    id 'org.springframework.boot' version '2.7.0'
    id 'io.spring.dependency-management' version '1.0.11.RELEASE'

    // 条件应用插件
    if (project.hasProperty('android')) {
        id 'com.android.application'
    }
}

// ==================== 2. 项目属性 ====================
group = 'com.example'
version = '1.0.0-SNAPSHOT'
description = 'My Gradle Project'

// Java配置
java {
    sourceCompatibility = JavaVersion.VERSION_11
    targetCompatibility = JavaVersion.VERSION_11
    withJavadocJar()
    withSourcesJar()
}

// ==================== 3. 仓库配置详解 ====================
repositories {
    // 仓库优先级:从上到下依次查找

    // 1. 本地Maven仓库(最快)
    mavenLocal()
    // 位置:~/.m2/repository
    // 优势:本地缓存,访问最快
    // 注意:可能包含SNAPSHOT版本,生产环境需谨慎

    // 2. Maven中央仓库(最权威)
    mavenCentral()
    // 地址:https://repo1.maven.org/maven2/
    // 优势:官方仓库,最可靠
    // 包含:大部分开源项目的正式版本

    // 3. Gradle插件门户
    gradlePluginPortal()
    // 地址:https://plugins.gradle.org/
    // 用途:Gradle插件专用仓库

    // 4. 国内镜像仓库(加速访问)
    maven {
        name = 'Aliyun'
        url = 'https://maven.aliyun.com/repository/public'
        // 优势:国内访问速度快
        // 适用:开发环境加速下载
    }

    // 5. 特定用途仓库
    maven {
        name = 'Spring Milestones'
        url = 'https://repo.spring.io/milestone'
        // 内容过滤:只包含Spring相关依赖
        mavenContent {
            includeGroupByRegex 'org\\.springframework.*'
            includeGroup 'org.springframework.boot'
            includeGroup 'org.springframework.cloud'
        }
    }

    // 6. 企业私有仓库(需要认证)
    maven {
        name = 'CompanyNexus'
        url = 'https://nexus.company.com/repository/maven-public/'
        credentials {
            // 从gradle.properties读取认证信息
            username = project.findProperty('nexusUsername') ?: 'guest'
            password = project.findProperty('nexusPassword') ?: 'guest'
        }
        // 认证方式
        authentication {
            basic(BasicAuthentication)
        }
    }

    // 7. SNAPSHOT仓库
    maven {
        name = 'CompanySnapshots'
        url = 'https://nexus.company.com/repository/maven-snapshots/'
        credentials {
            username = project.findProperty('nexusUsername')
            password = project.findProperty('nexusPassword')
        }
        // 只包含SNAPSHOT版本
        mavenContent {
            snapshotsOnly()
        }
    }

    // 8. 条件仓库(根据环境决定)
    if (project.hasProperty('useInternalRepo')) {
        maven {
            name = 'InternalRepo'
            url = 'https://internal.company.com/repository/'
        }
    }
}

// 仓库配置最佳实践案例
repositories {
    // 开发环境:优先使用本地和镜像
    if (project.hasProperty('dev')) {
        mavenLocal()
        maven { url 'https://maven.aliyun.com/repository/public' }
        mavenCentral()
    }
    // 生产环境:只使用可靠仓库
    else {
        mavenCentral()
        maven {
            url 'https://nexus.company.com/repository/maven-public/'
            credentials {
                username nexusUsername
                password nexusPassword
            }
        }
    }
}

// ==================== 4. 依赖配置 ====================
// 版本管理
ext {
    springBootVersion = '2.7.0'
    junitVersion = '5.9.2'
    mockitoVersion = '4.11.0'
}

dependencies {
    // ==================== 编译时依赖 ====================
    // implementation: 编译和运行时需要,但不传递给消费者
    implementation "org.springframework.boot:spring-boot-starter-web:${springBootVersion}"
    // 说明:Spring Boot Web启动器,包含Spring MVC、Tomcat等
    // 使用场景:Web应用开发的核心依赖

    implementation 'org.apache.commons:commons-lang3:3.12.0'
    // 说明:Apache Commons工具库,提供字符串、数组等工具方法
    // 使用场景:日常开发中的工具类需求

    implementation 'com.fasterxml.jackson.core:jackson-databind:2.13.3'
    // 说明:JSON序列化/反序列化库
    // 使用场景:API数据交换、配置文件解析

    // ==================== 编译时专用依赖 ====================
    // compileOnly: 编译时需要,运行时由容器或环境提供
    compileOnly 'javax.servlet:javax.servlet-api:4.0.1'
    // 说明:Servlet API,运行时由Tomcat等容器提供
    // 使用场景:Web应用开发,避免与容器版本冲突

    compileOnly 'org.projectlombok:lombok:1.18.24'
    // 说明:Lombok注解处理器,编译时生成代码
    // 使用场景:减少样板代码,如getter/setter

    // ==================== 运行时依赖 ====================
    // runtimeOnly: 运行时需要,编译时不需要
    runtimeOnly 'mysql:mysql-connector-java:8.0.33'
    // 说明:MySQL数据库驱动
    // 使用场景:数据库连接,编译时不直接使用

    runtimeOnly 'com.h2database:h2:2.1.214'
    // 说明:H2内存数据库
    // 使用场景:开发和测试环境的轻量级数据库

    // ==================== 注解处理器 ====================
    // annotationProcessor: 编译时注解处理
    annotationProcessor 'org.springframework.boot:spring-boot-configuration-processor'
    // 说明:Spring Boot配置元数据生成器
    // 作用:为@ConfigurationProperties生成元数据,支持IDE自动补全

    annotationProcessor 'org.projectlombok:lombok:1.18.24'
    // 说明:Lombok注解处理器
    // 作用:编译时生成getter、setter、toString等方法

    // ==================== 测试依赖 ====================
    // testImplementation: 测试编译和运行时需要
    testImplementation "org.junit.jupiter:junit-jupiter:${junitVersion}"
    // 说明:JUnit 5测试框架
    // 使用场景:单元测试、集成测试

    testImplementation "org.mockito:mockito-core:${mockitoVersion}"
    // 说明:Mock框架,用于创建测试替身
    // 使用场景:单元测试中模拟依赖对象

    testImplementation 'org.springframework.boot:spring-boot-starter-test'
    // 说明:Spring Boot测试启动器,包含多个测试库
    // 包含:JUnit、Mockito、AssertJ、Hamcrest等

    testImplementation 'org.testcontainers:junit-jupiter:1.17.3'
    // 说明:Testcontainers集成测试框架
    // 使用场景:使用Docker容器进行集成测试

    testImplementation 'org.testcontainers:mysql:1.17.3'
    // 说明:MySQL Testcontainer
    // 使用场景:数据库集成测试

    // ==================== 测试运行时依赖 ====================
    // testRuntimeOnly: 测试运行时需要,测试编译时不需要
    testRuntimeOnly 'org.junit.platform:junit-platform-launcher'
    // 说明:JUnit平台启动器
    // 作用:IDE和构建工具运行测试时需要
}

// ==================== 依赖配置实战案例 ====================

// 案例1:Spring Boot Web应用完整依赖配置
dependencies {
    // Web层
    implementation 'org.springframework.boot:spring-boot-starter-web'
    implementation 'org.springframework.boot:spring-boot-starter-validation'

    // 数据层
    implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
    runtimeOnly 'mysql:mysql-connector-java'

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

    // 监控
    implementation 'org.springframework.boot:spring-boot-starter-actuator'
    implementation 'io.micrometer:micrometer-registry-prometheus'

    // 工具类
    implementation 'org.apache.commons:commons-lang3'
    compileOnly 'org.projectlombok:lombok'
    annotationProcessor 'org.projectlombok:lombok'

    // 测试
    testImplementation 'org.springframework.boot:spring-boot-starter-test'
    testImplementation 'org.springframework.security:spring-security-test'
    testImplementation 'org.testcontainers:mysql'
    testRuntimeOnly 'com.h2database:h2'
}

// 案例2:微服务项目依赖配置
dependencies {
    // Spring Cloud
    implementation 'org.springframework.cloud:spring-cloud-starter-netflix-eureka-client'
    implementation 'org.springframework.cloud:spring-cloud-starter-config'
    implementation 'org.springframework.cloud:spring-cloud-starter-sleuth'

    // 服务间通信
    implementation 'org.springframework.cloud:spring-cloud-starter-openfeign'
    implementation 'org.springframework.cloud:spring-cloud-starter-loadbalancer'

    // 消息队列
    implementation 'org.springframework.boot:spring-boot-starter-amqp'

    // 缓存
    implementation 'org.springframework.boot:spring-boot-starter-data-redis'

    // 基础依赖
    implementation 'org.springframework.boot:spring-boot-starter-web'
    implementation 'org.springframework.boot:spring-boot-starter-actuator'
}

// ==================== 5. 任务配置 ====================
// 测试配置
tasks.named('test') {
    useJUnitPlatform()

    // 测试JVM参数
    jvmArgs = ['-Xmx1024m']

    // 系统属性
    systemProperty 'spring.profiles.active', 'test'

    // 测试报告
    reports {
        html.required = true
        junitXml.required = true
    }

    // 测试事件监听
    testLogging {
        events 'passed', 'skipped', 'failed'
        exceptionFormat = 'full'
    }
}

// 编译配置
tasks.withType(JavaCompile) {
    options.encoding = 'UTF-8'
    options.compilerArgs += ['-parameters', '-Xlint:unchecked']
}

// JAR配置
jar {
    manifest {
        attributes(
            'Implementation-Title': project.name,
            'Implementation-Version': project.version,
            'Main-Class': 'com.example.Application'
        )
    }

    // 排除文件
    exclude 'META-INF/*.RSA', 'META-INF/*.SF', 'META-INF/*.DSA'
}

// ==================== 6. 自定义任务 ====================
task printProjectInfo {
    group = 'help'
    description = '打印项目信息'

    doLast {
        println "Project: ${project.name}"
        println "Version: ${project.version}"
        println "Java Version: ${java.sourceCompatibility}"
        println "Dependencies: ${configurations.runtimeClasspath.files.size()}"
    }
}

// ==================== 7. 应用配置 ====================
application {
    mainClass = 'com.example.Application'
    applicationDefaultJvmArgs = ['-Xmx512m']
}

// ==================== 8. 发布配置 ====================
publishing {
    publications {
        maven(MavenPublication) {
            from components.java

            pom {
                name = project.name
                description = project.description
                url = 'https://github.com/example/my-project'

                licenses {
                    license {
                        name = 'Apache License 2.0'
                        url = 'https://www.apache.org/licenses/LICENSE-2.0'
                    }
                }

                developers {
                    developer {
                        id = 'johndoe'
                        name = 'John Doe'
                        email = 'john@example.com'
                    }
                }
            }
        }
    }

    repositories {
        maven {
            name = 'CompanyNexus'
            url = version.endsWith('SNAPSHOT') ?
                'https://nexus.company.com/repository/maven-snapshots/' :
                'https://nexus.company.com/repository/maven-releases/'
            credentials {
                username = project.findProperty('nexusUsername')
                password = project.findProperty('nexusPassword')
            }
        }
    }
}
4.3 Kotlin DSL 对比

📝 build.gradle.kts 示例

// Kotlin DSL语法
plugins {
    java
    application
    id("org.springframework.boot") version "2.7.0"
}

group = "com.example"
version = "1.0.0"

java {
    sourceCompatibility = JavaVersion.VERSION_11
    targetCompatibility = JavaVersion.VERSION_11
}

repositories {
    mavenCentral()
}

dependencies {
    implementation("org.springframework.boot:spring-boot-starter-web")
    testImplementation("org.junit.jupiter:junit-jupiter:5.9.2")
}

tasks.named<Test>("test") {
    useJUnitPlatform()
}

application {
    mainClass.set("com.example.Application")
}

🔍 Groovy vs Kotlin DSL 对比

特性Groovy DSLKotlin DSL
语法动态、简洁静态类型、严格
IDE支持基础支持优秀的代码补全和重构
性能运行时解析编译时检查
学习曲线较平缓需要Kotlin知识
错误检测运行时编译时
重构支持有限强大

🔍 5. 依赖管理深度实践

5.1 依赖配置详解

📦 依赖配置类型

配置说明编译时运行时测试时传递性
implementation实现依赖(推荐)
apiAPI依赖
compileOnly仅编译时
runtimeOnly仅运行时
testImplementation测试实现
testCompileOnly测试编译时
testRuntimeOnly测试运行时

🔧 实际应用示例

dependencies {
    // implementation: 内部实现,不暴露给消费者
    implementation 'org.springframework:spring-core:5.3.21'
    implementation 'com.fasterxml.jackson.core:jackson-databind:2.13.3'

    // api: 公共API,会传递给消费者(仅在java-library插件中可用)
    api 'org.apache.commons:commons-lang3:3.12.0'

    // compileOnly: 编译时需要,运行时由容器提供
    compileOnly 'javax.servlet:javax.servlet-api:4.0.1'
    compileOnly 'org.projectlombok:lombok:1.18.24'

    // runtimeOnly: 运行时依赖,如数据库驱动
    runtimeOnly 'mysql:mysql-connector-java:8.0.33'
    runtimeOnly 'com.h2database:h2:2.1.214'

    // annotationProcessor: 注解处理器
    annotationProcessor 'org.projectlombok:lombok:1.18.24'
    annotationProcessor 'org.springframework.boot:spring-boot-configuration-processor'

    // 测试依赖
    testImplementation 'org.junit.jupiter:junit-jupiter:5.9.2'
    testImplementation 'org.mockito:mockito-core:4.11.0'
    testImplementation 'org.springframework.boot:spring-boot-starter-test'

    // 测试运行时
    testRuntimeOnly 'org.junit.platform:junit-platform-launcher'
}
5.2 版本管理策略

🎯 版本声明方式

dependencies {
    // 1. 直接指定版本
    implementation 'org.springframework:spring-core:5.3.21'

    // 2. 使用变量管理版本
    implementation "org.springframework:spring-core:${springVersion}"

    // 3. 使用ext属性
    implementation "org.springframework:spring-core:${ext.springVersion}"

    // 4. 版本范围(不推荐生产环境)
    implementation 'org.springframework:spring-core:5.+'
    implementation 'org.springframework:spring-core:[5.0,6.0)'

    // 5. 最新版本(不推荐)
    implementation 'org.springframework:spring-core:latest.release'
}

// 版本管理最佳实践
ext {
    springVersion = '5.3.21'
    junitVersion = '5.9.2'
    mockitoVersion = '4.11.0'
}

// 或使用gradle.properties
// springVersion=5.3.21
// junitVersion=5.9.2

🔧 依赖约束和BOM

// 使用Spring Boot BOM
dependencies {
    // 导入BOM
    implementation platform('org.springframework.boot:spring-boot-dependencies:2.7.0')

    // 无需指定版本,由BOM管理
    implementation 'org.springframework.boot:spring-boot-starter-web'
    implementation 'org.springframework.boot:spring-boot-starter-data-jpa'

    // 覆盖BOM版本
    implementation 'com.fasterxml.jackson.core:jackson-core:2.14.0'
}

// 自定义依赖约束
dependencyManagement {
    dependencies {
        dependency 'org.apache.commons:commons-lang3:3.12.0'
        dependency 'com.google.guava:guava:31.1-jre'
    }
}
5.3 依赖冲突解决

🔍 查看依赖树

# 查看所有依赖
./gradlew dependencies

# 查看特定配置的依赖
./gradlew dependencies --configuration runtimeClasspath

# 查看依赖洞察
./gradlew dependencyInsight --dependency spring-core

# 查看依赖冲突
./gradlew dependencies --configuration runtimeClasspath | grep "(*)"

🛠️ 解决冲突策略

dependencies {
    implementation 'org.springframework:spring-core:5.3.21'

    // 1. 排除传递依赖
    implementation('org.springframework:spring-context:5.3.21') {
        exclude group: 'commons-logging', module: 'commons-logging'
    }

    // 2. 排除所有传递依赖
    implementation('some.group:some-module:1.0') {
        transitive = false
    }

    // 3. 强制使用特定版本
    implementation 'commons-logging:commons-logging:1.2'
}

// 全局依赖解析策略
configurations.all {
    resolutionStrategy {
        // 强制使用特定版本
        force 'commons-logging:commons-logging:1.2'

        // 版本冲突时失败
        failOnVersionConflict()

        // 缓存动态版本
        cacheDynamicVersionsFor 10, 'minutes'
        cacheChangingModulesFor 4, 'hours'

        // 替换模块
        dependencySubstitution {
            substitute module('commons-logging:commons-logging') with module('org.slf4j:jcl-over-slf4j:1.7.36')
        }
    }
}

📌 第三阶段:Gradle 任务系统与插件

⚙️ 6. 任务系统深度解析

6.1 任务基础概念

🎯 任务的生命周期

// 任务定义阶段
task myTask {
    // 配置阶段执行
    println 'Configuring myTask'

    // 执行阶段
    doFirst {
        println 'Before myTask execution'
    }

    doLast {
        println 'After myTask execution'
    }
}

// 任务配置
myTask {
    description = 'My custom task'
    group = 'custom'
}

🔧 任务类型

// 1. Ad-hoc任务(简单任务)
task hello {
    doLast {
        println 'Hello, Gradle!'
    }
}

// 2. 类型化任务
task copyFiles(type: Copy) {
    from 'src/main/resources'
    into 'build/resources'
}

task createZip(type: Zip) {
    from 'src/main/java'
    archiveFileName = 'sources.zip'
    destinationDirectory = file('build/distributions')
}

// 3. 自定义任务类
class GreetingTask extends DefaultTask {
    @Input
    String greeting = 'hello'

    @Input
    String recipient = 'world'

    @TaskAction
    void greet() {
        println "${greeting}, ${recipient}!"
    }
}

task greeting(type: GreetingTask) {
    greeting = 'Hi'
    recipient = 'Gradle'
}
6.2 任务依赖与排序

🔗 任务依赖

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

task taskB {
    doLast {
        println 'Task B'
    }
}

task taskC {
    // 依赖taskA和taskB
    dependsOn taskA, taskB
    doLast {
        println 'Task C'
    }
}

// 动态依赖
task taskD {
    dependsOn tasks.matching { task -> task.name.startsWith('test') }
    doLast {
        println 'Task D'
    }
}

// 条件依赖
taskC.dependsOn {
    tasks.findAll { task -> task.name.startsWith('compile') && task.enabled }
}

📋 任务排序

task taskX {
    doLast { println 'Task X' }
}

task taskY {
    doLast { println 'Task Y' }
}

// mustRunAfter: 如果两个任务都要执行,确保顺序
taskY.mustRunAfter taskX

// shouldRunAfter: 软排序,尽量保证顺序
taskY.shouldRunAfter taskX

// finalizedBy: 无论成功失败都会执行
task cleanup {
    doLast { println 'Cleanup' }
}

taskX.finalizedBy cleanup
6.3 任务输入输出

📁 任务输入输出管理详解

// ==================== 基础输入输出配置 ====================
task processFiles {
    // 输入文件配置
    inputs.files fileTree('src/main/resources') {
        include '**/*.properties'
        include '**/*.yml'
        exclude '**/*.tmp'
    }

    // 输入属性配置
    inputs.property 'version', project.version
    inputs.property 'environment', project.findProperty('env') ?: 'dev'

    // 输出目录配置
    outputs.dir 'build/processed'

    // 缓存配置
    outputs.cacheIf { true }

    // 增量构建配置
    outputs.upToDateWhen {
        // 自定义最新检查逻辑
        file('build/processed').exists() &&
        file('build/processed').lastModified() > inputs.files.asFileTree.maxBy { it.lastModified() }.lastModified()
    }

    doLast {
        // 确保输出目录存在
        outputs.files.singleFile.mkdirs()

        // 处理文件
        copy {
            from inputs.files
            into outputs.files.singleFile
            filter { line ->
                line.replace('${version}', project.version)
                    .replace('${env}', project.findProperty('env') ?: 'dev')
            }
        }

        println "Processed ${inputs.files.files.size()} files to ${outputs.files.singleFile}"
    }
}

// ==================== 使用注解的任务类 ====================
class ProcessFilesTask extends DefaultTask {

    // 输入文件:支持增量构建
    @InputFiles
    @PathSensitive(PathSensitivity.RELATIVE)
    FileCollection inputFiles

    // 输入属性:影响任务执行结果
    @Input
    String version

    @Input
    @Optional
    String environment = 'dev'

    // 输出目录:任务的产出
    @OutputDirectory
    File outputDir

    // 内部属性:不影响任务最新状态
    @Internal
    String logLevel = 'INFO'

    @TaskAction
    void processFiles() {
        // 确保输出目录存在
        outputDir.mkdirs()

        // 处理每个输入文件
        inputFiles.each { file ->
            def outputFile = new File(outputDir, file.name)

            outputFile.text = file.text
                .replace('${version}', version)
                .replace('${environment}', environment)

            if (logLevel == 'DEBUG') {
                println "Processed: ${file.name} -> ${outputFile.name}"
            }
        }

        println "Processed ${inputFiles.files.size()} files for environment: ${environment}"
    }
}

// 注册自定义任务
tasks.register('processConfigFiles', ProcessFilesTask) {
    inputFiles = fileTree('src/main/resources/config')
    version = project.version
    environment = project.findProperty('env') ?: 'dev'
    outputDir = file('build/processed-config')
}

// ==================== 复杂任务输入输出示例 ====================
task generateDocumentation {
    // 多种输入类型
    inputs.files fileTree('src/main/java') {
        include '**/*.java'
    }
    inputs.files fileTree('docs/templates')
    inputs.property 'version', project.version
    inputs.property 'buildTime', new Date().format('yyyy-MM-dd HH:mm:ss')

    // 多个输出
    outputs.dir 'build/docs/api'
    outputs.dir 'build/docs/user-guide'
    outputs.file 'build/docs/README.html'

    // 缓存配置
    outputs.cacheIf {
        // 只有在生产环境才缓存文档生成
        project.hasProperty('prod')
    }

    doLast {
        // 生成API文档
        exec {
            commandLine 'javadoc', '-d', 'build/docs/api',
                       '-sourcepath', 'src/main/java',
                       '-subpackages', 'com.example'
        }

        // 生成用户指南
        copy {
            from 'docs/templates'
            into 'build/docs/user-guide'
            expand(
                version: project.version,
                buildTime: new Date().format('yyyy-MM-dd HH:mm:ss')
            )
        }

        // 生成README
        def readmeContent = """
        # ${project.name} v${project.version}

        Generated on: ${new Date().format('yyyy-MM-dd HH:mm:ss')}

        ## API Documentation
        See [API Docs](api/index.html)

        ## User Guide
        See [User Guide](user-guide/index.html)
        """.stripIndent()

        file('build/docs/README.html').text = readmeContent
    }
}

// ==================== 任务输入输出最佳实践 ====================

// 1. 文件复制任务
task copyResources(type: Copy) {
    from 'src/main/resources'
    into 'build/resources'

    // 输入输出自动配置
    // inputs.files 自动设置为 from 的文件
    // outputs.dir 自动设置为 into 的目录

    // 文件过滤
    filter { line ->
        line.replace('${project.version}', project.version)
    }

    // 包含/排除文件
    include '**/*.properties'
    exclude '**/*.tmp'
}

// 2. ZIP打包任务
task createDistribution(type: Zip) {
    archiveFileName = "${project.name}-${project.version}.zip"
    destinationDirectory = file('build/distributions')

    from 'build/libs'
    from 'src/main/scripts'
    from 'README.md'

    // 自动配置输入输出
    // inputs 包含所有 from 的文件
    // outputs.file 为生成的ZIP文件
}

// 3. 测试任务配置
tasks.named('test') {
    // 输入配置
    inputs.files sourceSets.test.runtimeClasspath
    inputs.files sourceSets.main.runtimeClasspath
    inputs.property 'javaVersion', System.getProperty('java.version')

    // 输出配置
    outputs.dir 'build/test-results'
    outputs.dir 'build/reports/tests'

    // 缓存配置
    outputs.cacheIf {
        // 只有在没有系统属性变化时才缓存
        !project.hasProperty('rerunTests')
    }
}

🔌 7. 插件系统详解

7.1 插件应用方式

📦 插件应用语法

// 1. 核心插件(推荐)
plugins {
    id 'java'
    id 'application'
}

// 2. 社区插件
plugins {
    id 'org.springframework.boot' version '2.7.0'
    id 'io.spring.dependency-management' version '1.0.11.RELEASE'
}

// 3. 传统方式(不推荐)
apply plugin: 'java'
apply plugin: 'application'

// 4. 条件应用
plugins {
    id 'java'
    if (project.hasProperty('android')) {
        id 'com.android.application'
    }
}

// 5. 脚本插件
apply from: 'gradle/dependencies.gradle'
apply from: 'https://raw.githubusercontent.com/example/scripts/main/common.gradle'
7.2 常用插件详解

☕ Java插件

plugins {
    id 'java'
}

// Java插件配置
java {
    sourceCompatibility = JavaVersion.VERSION_11
    targetCompatibility = JavaVersion.VERSION_11

    // 生成源码jar
    withSourcesJar()

    // 生成javadoc jar
    withJavadocJar()
}

// 编译配置
compileJava {
    options.encoding = 'UTF-8'
    options.compilerArgs += ['-parameters', '-Xlint:unchecked']
}

// 测试配置
test {
    useJUnitPlatform()

    testLogging {
        events 'passed', 'skipped', 'failed'
    }

    reports {
        html.required = true
        junitXml.required = true
    }
}

🌐 Application插件

plugins {
    id 'application'
}

application {
    mainClass = 'com.example.Application'
    applicationDefaultJvmArgs = ['-Xmx512m', '-Dfile.encoding=UTF-8']
}

// 生成的任务
// run: 运行应用
// distZip: 创建ZIP分发包
// distTar: 创建TAR分发包
// installDist: 安装应用到build/install

🌸 Spring Boot插件

plugins {
    id 'org.springframework.boot' version '2.7.0'
    id 'io.spring.dependency-management' version '1.0.11.RELEASE'
}

springBoot {
    buildInfo()

    mainClass = 'com.example.Application'
}

// 生成的任务
// bootRun: 运行Spring Boot应用
// bootJar: 创建可执行JAR
// bootBuildImage: 构建Docker镜像

📚 下篇预告:在下篇中,我们将深入探讨多项目构建、自定义插件开发、性能优化技巧,以及完整的企业级实战案例和最佳实践。


💡 学习建议:上篇内容是Gradle学习的基础,建议通过创建实际项目来练习DSL语法、任务配置和插件使用,为学习下篇的高级内容做好准备。Gradle的强大之处在于其灵活性,需要多实践才能熟练掌握。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值