如果 Gradle 或 Gradle 社区没有提供您的项目所需的特定功能,那么创建您自己的自定义插件可能是一个解决方案。
此外,如果您发现自己在子项目之间重复构建逻辑,并且需要一种更好的方式来组织它,约定插件可以提供帮助。
脚本插件
插件是任何实现 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
。
要应用一个插件,只需使用从脚本文件名(不带 .gradle
)派生的 ID
。您可以将文件本身视为插件,因此您不需要在预编译脚本中子类化 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
}
请查阅 开发插件章节 以了解更多信息。