如果 Gradle 或 Gradle 社区没有提供您的项目所需的特定功能,那么创建您自己的自定义插件可能是一个解决方案。
此外,如果您发现在多个子项目之间重复构建逻辑,并且需要更好的组织方式,约定插件(convention plugins)可以提供帮助。
脚本插件
插件是任何实现了 Plugin
接口的类。例如,这是一个 "hello world" 插件
abstract class SamplePlugin : Plugin<Project> { (1)
override fun apply(project: Project) { (2)
project.tasks.register("ScriptPlugin") {
doLast {
println("Hello world from the build file!")
}
}
}
}
apply<SamplePlugin>() (3)
class SamplePlugin implements Plugin<Project> { (1)
void apply(Project project) { (2)
project.tasks.register("ScriptPlugin") {
doLast {
println("Hello world from the build file!")
}
}
}
}
apply plugin: SamplePlugin (3)
1 | 扩展 org.gradle.api.Plugin 接口。 |
2 | 覆盖 apply 方法。 |
3 | 将插件 apply 到项目。 |
1. 扩展 org.gradle.api.Plugin
接口
创建一个扩展 Plugin
接口的类
abstract class SamplePlugin : Plugin<Project> {
}
class SamplePlugin implements Plugin<Project> {
}
2. 覆盖 apply
方法
在 apply()
方法中添加任务和其他逻辑
override fun apply() {
}
void apply(Project project) {
}
3. 将插件 apply
到你的项目
当 SamplePlugin
应用到你的项目时,Gradle 会调用定义的 fun apply() {}
方法。这会将 ScriptPlugin
任务添加到你的项目
apply<SamplePlugin>()
apply plugin: SamplePlugin
请注意,这是一个简单的 hello-world
示例,并且不代表最佳实践。
脚本插件不推荐使用。 |
开发插件的最佳实践是创建约定插件或二进制插件。
预编译脚本插件
预编译脚本插件提供了一种快速原型设计和实验的简便方法。它们允许您使用 Groovy 或 Kotlin DSL 将构建逻辑打包为 *.gradle(.kts)
脚本文件。这些脚本位于特定目录中,例如 src/main/groovy
或 src/main/kotlin
。
要应用一个预编译脚本插件,只需使用从脚本文件名派生的 ID
(不带 .gradle
后缀)。您可以将文件本身视为插件,因此在预编译脚本中无需子类化 Plugin
接口。
让我们看看一个具有以下结构的示例
.
└── buildSrc
├── build.gradle.kts
└── src
└── main
└── kotlin
└── my-create-file-plugin.gradle.kts
我们的 my-create-file-plugin.gradle.kts
文件包含以下代码
abstract class CreateFileTask : DefaultTask() {
@get:Input
abstract val fileText: Property<String>
@Input
val fileName = "myfile.txt"
@OutputFile
val myFile: File = File(fileName)
@TaskAction
fun action() {
myFile.createNewFile()
myFile.writeText(fileText.get())
}
}
tasks.register<CreateFileTask>("createMyFileTaskInConventionPlugin") {
group = "from my convention plugin"
description = "Create myfile.txt in the current directory"
fileText.set("HELLO FROM MY CONVENTION PLUGIN")
}
abstract class CreateFileTask extends DefaultTask {
@Input
abstract Property<String> getFileText()
@Input
String fileName = "myfile.txt"
@OutputFile
File getMyFile() {
return new File(fileName)
}
@TaskAction
void action() {
myFile.createNewFile()
myFile.writeText(fileText.get())
}
}
tasks.register("createMyFileTaskInConventionPlugin", CreateFileTask) {
group = "from my convention plugin"
description = "Create myfile.txt in the current directory"
fileText.set("HELLO FROM MY CONVENTION PLUGIN")
}
现在可以将预编译脚本应用到任何子项目的 build.gradle(.kts
) 文件中
plugins {
id("my-create-file-plugin") // Apply the pre-compiled convention plugin
`kotlin-dsl`
}
plugins {
id 'my-create-file-plugin' // Apply the pre-compiled convention plugin
id 'groovy' // Apply the Groovy DSL plugin
}
插件中的 createFileTask
任务现在在您的子项目中可用。
二进制插件
二进制插件是使用编译型语言实现的插件,并打包为 JAR 文件。它作为依赖项解析,而不是从源代码编译。
对于大多数用例,约定插件无需频繁更新。让每个开发人员在其开发过程中执行插件构建是浪费时间的,我们可以改为将它们作为二进制依赖项分发。
有两种方法可以将上面示例中的约定插件更新为二进制插件。
我们采用第二种解决方案。此插件已用 Kotlin 重写,名为 MyCreateFileBinaryPlugin.kt
。它仍存储在 buildSrc
中
import org.gradle.api.DefaultTask
import org.gradle.api.Plugin
import org.gradle.api.Project
import org.gradle.api.provider.Property
import org.gradle.api.tasks.Input
import org.gradle.api.tasks.OutputFile
import org.gradle.api.tasks.TaskAction
import java.io.File
abstract class CreateFileTask : DefaultTask() {
@get:Input
abstract val fileText: Property<String>
@Input
val filePath = project.layout.settingsDirectory.file("myfile.txt").asFile.path
@OutputFile
val myFile: File = File(filePath)
@TaskAction
fun action() {
myFile.createNewFile()
myFile.writeText(fileText.get())
}
}
class MyCreateFileBinaryPlugin : Plugin<Project> {
override fun apply(project: Project) {
project.tasks.register("createFileTaskFromBinaryPlugin", CreateFileTask::class.java) {
group = "from my binary plugin"
description = "Create myfile.txt in the current directory"
fileText.set("HELLO FROM MY BINARY PLUGIN")
}
}
}
可以使用 gradlePlugin{}
块发布插件并为其指定一个 id
,以便在根目录中引用它
group = "com.example"
version = "1.0.0"
gradlePlugin {
plugins {
create("my-binary-plugin") {
id = "com.example.my-binary-plugin"
implementationClass = "MyCreateFileBinaryPlugin"
}
}
}
publishing {
repositories {
mavenLocal()
}
}
group = 'com.example'
version = '1.0.0'
gradlePlugin {
plugins {
create("my-binary-plugin") {
id = "com.example.my-binary-plugin"
implementationClass = "MyCreateFileBinaryPlugin"
}
}
}
publishing {
repositories {
mavenLocal()
}
}
然后,可以在构建文件中应用该插件
plugins {
id("my-create-file-plugin") // Apply the pre-compiled convention plugin
id("com.example.my-binary-plugin") // Apply the binary plugin
`kotlin-dsl`
}
plugins {
id 'my-create-file-plugin' // Apply the pre-compiled convention plugin
id 'com.example.my-binary-plugin' // Apply the binary plugin
id 'groovy' // Apply the Groovy DSL plugin
}
查阅 开发插件章节 以了解更多信息。