Skip to content

懒加载配置

懒加载(Lazy Configuration)是 Gradle 的重要性能特性,通过推迟值的计算到真正需要时,避免配置阶段的不必要工作。

为什么需要懒加载?

kotlin
// ❌ 立即计算(配置阶段执行,即使任务不运行)
tasks.register("publish") {
    val version = readVersionFromFile()  // 立即执行!
    doLast { println("Version: $version") }
}

// ✅ 懒加载(只在任务执行时计算)
tasks.register("publish") {
    val version = providers.fileContents(layout.projectDirectory.file("version.txt")).asText
    doLast { println("Version: ${version.get()}") }
}

Property API

kotlin
// Property<T>:可读写
abstract class MyTask : DefaultTask() {
    @get:Input
    abstract val name: Property<String>
    
    @get:OutputFile
    abstract val outputFile: RegularFileProperty
}

// 设置值
tasks.register<MyTask>("myTask") {
    name.set("hello")
    name.set(provider { computeExpensiveName() })  // 懒加载
    outputFile.set(layout.buildDirectory.file("output.txt"))
}

Provider API

kotlin
// Provider<T>:只读,值的来源

// 从 Gradle 属性
val version = providers.gradleProperty("myVersion")

// 从环境变量
val apiKey = providers.environmentVariable("API_KEY")

// 从系统属性
val debug = providers.systemProperty("debug")

// 从文件内容
val config = providers.fileContents(layout.projectDirectory.file("config.txt")).asText

// 从 exec 命令
val gitHash = providers.exec {
    commandLine("git", "rev-parse", "--short", "HEAD")
}.standardOutput.asText.map { it.trim() }

// 组合 Provider
val fullVersion = version.zip(gitHash) { v, h -> "$v-$h" }
val safeVersion = version.orElse("0.0.0-SNAPSHOT")

文件 Provider API

kotlin
// DirectoryProperty 和 RegularFileProperty
val buildDir: DirectoryProperty = layout.buildDirectory
val outputFile: Provider<RegularFile> = buildDir.file("output.jar")
val outputDir: Provider<Directory> = buildDir.dir("classes")

// 组合路径
val nestedFile = buildDir.dir("reports").map { it.file("result.html") }

懒加载任务配置

kotlin
// tasks.named() 是懒加载(不立即配置任务)
tasks.named<Test>("test") {
    // 只在需要 test 任务时才执行此配置块
    useJUnitPlatform()
}

// tasks.register() 也是懒加载
val myTask = tasks.register("myTask") {
    // 只在任务首次被访问时才执行
}

// 注意:tasks.create() 是立即执行(不推荐)
// tasks.create("myTask") { }

下一步