Gradle 深入解析
kotlin plugins { id("java") }
group = "com.example" version = "1.0.0"
repositories { mavenCentral() }
dependencies { testImplementation("org.junit.jupiter:junit-jupiter:5.9.3") }
- `plugins{}` 块:应用官方或社区插件。
- `repositories{}`:指定依赖查找的仓库。
- `dependencies{}`:声明项目的依赖。
Groovy DSL 语法类似,但字符串和函数调用略有差异。
### 3. 任务(Task)详解
任务是 Gradle 的核心执行单位。下面深入介绍如何创建和定制任务。
#### 3.1 创建任务
可以在构建脚本中通过任务容器注册任务:
```kotlin
// 使用register方式(推荐,延迟配置)
tasks.register("hello") {
doLast {
println("Hello Gradle!")
}
}
// 使用create方式(立即配置)
tasks.create("greet") {
doFirst {
println("Greet executed first")
}
doLast {
println("Greet executed last")
}
}
doLast:添加一个在任务执行最后执行的动作(Action)。doFirst:添加在最前的动作。- 推荐使用
register,因为它延迟配置,仅在需要时才创建任务,能提升构建性能。
3.2 任务依赖
通过 dependsOn 设置任务间的依赖关系:
tasks.register("prepare") {
doLast { println("Preparing...") }
}
tasks.register("assemble") {
dependsOn("prepare")
doLast { println("Assembling...") }
}
可以通过命令行执行 gradle assemble,Gradle 会先执行 prepare 再执行 assemble。也可以为依赖指定数组,实现多重依赖。
3.3 任务输入与输出
声明任务的输入和输出是实现增量构建的关键。Gradle 可以根据输入输出的变化决定是否跳过任务。
tasks.register<Copy>("copyConfig") {
from("src/config")
into("build/config")
}
对于自定义任务,可以使用 inputs 和 outputs 属性:
abstract class MyTask : DefaultTask() {
@InputFile
lateinit var inputFile: File
@OutputFile
lateinit var outputFile: File
@TaskAction
fun process() {
// 处理逻辑
}
}
仅为有输入输出变化的任务重新执行,大幅加快构建速度。
3.4 任务类型
Gradle 内置了丰富的任务类型,如 Copy、Delete、Exec、JavaCompile 等。你可以直接使用或继承它们。
tasks.register<Zip>("bundle") {
from("src/main/resources")
archiveFileName.set("bundle.zip")
destinationDirectory.set(layout.buildDirectory.dir("dist"))
}
4. 依赖管理
Gradle 提供了强大的依赖管理功能,能够声明、解析和使用来自不同仓库的依赖。
4.1 依赖配置
声明依赖时需要指定配置(Configuration),表示依赖使用的范围。常见配置包括:
- implementation:依赖仅在模块内部使用,不会泄露给编译时消费者。推荐使用。
- api:依赖会暴露给消费者(即如果其他项目依赖本项目,能传递性获得本依赖)。
- compileOnly:编译时需要,但不会打包,运行时由环境提供。
- runtimeOnly:运行时需要,编译时不暴露。
- testImplementation、testCompileOnly等:测试相关的配置。
示例:
dependencies {
implementation("com.google.guava:guava:32.1.2-jre")
testImplementation("org.junit.jupiter:junit-jupiter:5.9.3")
compileOnly("org.projectlombok:lombok:1.18.28")
runtimeOnly("org.postgresql:postgresql:42.6.0")
}
4.2 外部依赖与版本
依赖的声明格式为 group:artifact:version。也可以使用动态版本:
implementation("org.springframework:spring-core:5.+") // 使用5.x的最新版本
implementation("com.google.guava:guava:[10.0,11.0)") // 版本范围
但为了构建可重现性,生产环境建议采用固定版本。
4.3 依赖冲突与传递性依赖
当一个依赖被多条路径引入且版本不同时,Gradle 会自动选择一个最高版本(默认策略)。可以用 resolutionStrategy 强制指定:
configurations.all {
resolutionStrategy {
force("com.google.guava:guava:31.1-jre")
}
}
也可以排除传递性依赖:
implementation("some:lib:1.0") {
exclude(group = "log4j", module = "log4j")
}
5. Gradle 插件体系
插件是 Gradle 扩展功能的单元。它们可以添加任务、配置、约定以及新的 DSL。
5.1 应用插件
在 plugins{} 块中声明插件:
plugins {
id("java") // 内置插件
id("org.springframework.boot") version "3.1.2" // 第三方插件
}
对于旧版的 apply plugin 方式,依然可用,但新项目建议采用 plugins DSL。
5.2 常用官方插件
- java / java-library:添加 Java 编译、测试、Jar 打包等任务。
- application:生成可执行 JVM 应用,提供
run任务和打包分发包的功能。 - maven-publish:用于发布构件到 Maven 仓库。
- checkstyle / pmd / spotbugs:静态代码分析。
- war:适用于 Web 应用,构建 WAR 包。
5.3 自定义插件
自定义插件可以打包在 buildSrc 目录或独立项目中。最简单的自定义插件方式:
在 buildSrc/src/main/kotlin/MyPlugin.kt 中:
class MyPlugin : Plugin<Project> {
override fun apply(project: Project) {
project.tasks.register("myTask") {
doLast { println("Hello from custom plugin") }
}
}
}
然后于主项目的 build.gradle.kts 中应用:
plugins {
id("my-plugin")
}
6. 多项目构建
大型项目通常由多个子模块构成,Gradle 提供了方便的多项目构建支持。
6.1 项目结构
在根目录创建 settings.gradle.kts 文件,包含所有子项目:
rootProject.name = "my-root"
include("core", "web", "data")
子项目分别位于 core/、web/、data/ 目录下,并各自拥有自己的 build.gradle.kts。
6.2 通用配置
根项目的构建脚本可以集中定义子项目共用的配置:
subprojects {
apply(plugin = "java")
group = "com.example"
version = "1.0"
repositories {
mavenCentral()
}
}
也可以通过 allprojects 应用于所有项目(包括根项目)。
6.3 跨项目依赖
在子项目之间声明依赖,使用项目路径:
// web/build.gradle.kts
dependencies {
implementation(project(":core"))
implementation(project(":data"))
}
这样 web 就能使用 core 和 data 模块中的类。
7. Gradle Wrapper:确保一致的构建环境
Wrapper 是 Gradle 推荐使用的执行方式。它是一套脚本和 Jar 包,允许在没有预装 Gradle 的机器上,自动下载指定版本的 Gradle 并执行构建。
7.1 使用方式
在项目根目录执行 gradle wrapper 生成 wrapper 文件。之后使用 ./gradlew(Unix)或 gradlew.bat(Windows)代替直接调用 gradle。
Wrapper 的关键文件:
gradlew/gradlew.bat:执行脚本。gradle/wrapper/gradle-wrapper.jar:负责下载 Gradle 的引导 Jar。gradle/wrapper/gradle-wrapper.properties:配置 Gradle 版本和存放路径。
7.2 配置版本
在 gradle-wrapper.properties 中指定:
distributionUrl=https\://services.gradle.org/distributions/gradle-8.2.1-bin.zip
通过 ./gradlew wrapper --gradle-version 8.3 可以快速升级或降级。
8. 常用的构建优化技巧
Gradle 自身具备很高的性能,但仍有一些优化手段值得掌握。
8.1 开启并行与按需配置
在 gradle.properties 中设置:
org.gradle.parallel=true
org.gradle.configureondemand=true
parallel使得多模块项目中的独立任务可以并行执行。configureondemand仅配置当前执行任务所需的项目,减少配置阶段耗时。
8.2 使用构建缓存
org.gradle.caching=true 启用本地构建缓存,使得任何任务的输出只要输入不变都能被重用,而不仅仅依赖任务的增量构建。
8.3 守护进程调优
Gradle 默认会启动守护进程。可以通过 gradle.properties 调整 JVM 参数:
org.gradle.jvmargs=-Xmx2048m -XX:MaxMetaspaceSize=512m