例如,与仅使用 String 类型相比,在 Gradle 插件中使用 Gradle Property 类型有什么好处?

Tho*_*oom 8 java android gradle kotlin gradle-plugin

  1. 在 Gradle 插件中,我可以将属性定义为:
open class ExamplePluginExtension {

    var exampleName: String? = null

}
Run Code Online (Sandbox Code Playgroud)

并在build.gradle.kts中访问它,如下所示:

example {

    exampleName = "Lorem Ipsum"

}
Run Code Online (Sandbox Code Playgroud)

或者2.我可以使用Gradle的Property类型(org.gradle.api.provider.Property):

open class ExamplePluginExtension @Inject constructor(objectFactory: ObjectFactory) {

    val exampleName: Property<String> = objectFactory.property(String::class.java)

}
Run Code Online (Sandbox Code Playgroud)

在build.gradle.kts中访问它,如下所示:

example {

    exampleName.set("Lorem Ipsum")

}
Run Code Online (Sandbox Code Playgroud)

Gradle 文档提倡在 Gradle 插件中使用 Property 类型,但为什么呢?使用 Property 类型非常麻烦,会创建大量样板文件并禁止使用可为 null 的属性。我看到很多第三方库比如Flyway都使用第一个选项,完全忽略了Property类型。

Sla*_*law 0

据我了解,属性的主要好处是延迟配置(如果使用正确)。它们还允许您定义常规值,甚至基于其他提供者,这意味着常规值也可以延迟计算。还有 . 提供的 API 的好处Property。其中包括类似isPresent和之类的方法getOrElse,可让您处理没有常规值的未设置属性。请注意,还有更专门类型的属性,例如ListPropertyDirectoryProperty,它们添加了更多方法。

使用属性并没有那么冗长,或者至少不再那么冗长了。您正在注入对象工厂并手动创建属性。但是您可以让 Gradle 为您创建和装饰扩展(或任务)类。它可能看起来像:

import org.gradle.api.provider.Property

abstract class ExamplePluginExtension {

     abstract val exampleName: Property<String>

     init {
         // There's an overload that accepts a Provider. Note it might 
         // be better to do this in the plugin class after creating the
         // extension, not sure).
         exampleName.convention("default name")
     }
}
Run Code Online (Sandbox Code Playgroud)

或者作为接口:

import org.gradle.api.provider.Property

interface ExamplePluginExtension {

    // If you want to set the conventional value, then you'd have to set it
    // somewhere else (e.g., in the plugin class after creating the extension).
    val exampleName: Property<String>
}
Run Code Online (Sandbox Code Playgroud)

然后你需要注册扩展:

import org.gradle.api.Plugin
import org.gradle.api.Project
import org.gradle.kotlin.dsl.*

class ExamplePlugin : Plugin<Project> {

    override fun apply(project: Project) {
        // this returns an instance of the extension class
        project.extensions.create("example", ExamplePluginExtension::class)
    }
}
Run Code Online (Sandbox Code Playgroud)

这将允许您在构建文件中执行以下操作:

plugins {
    // apply example plugin
}

example {
    exampleName = "Foo"
}
Run Code Online (Sandbox Code Playgroud)