插件介绍
插件可以来自 Gradle 或 Gradle 社区。但是,当用户想要组织他们的构建逻辑或需要现有插件未提供的特定构建功能时,他们可以开发自己的插件。
因此,我们区分三种不同类型的插件:
-
核心插件- 来自 Gradle 的插件。
-
社区插件- 来自Gradle 插件门户或公共存储库的插件。
-
本地或自定义插件- 您自己开发的插件。
社区插件
术语“社区插件”是指发布到 Gradle 插件门户(或其他公共存储库)的插件,例如Spotless 插件。
本地或自定义插件
术语本地或自定义插件是指您自己为自己的构建编写的插件。
构建脚本和脚本插件
构建脚本插件通常是在构建文件中编写的小型本地插件,用于特定于单个构建或项目的任务,并且不需要在多个项目中重用。不推荐使用构建脚本插件,但许多其他形式的插件是从构建脚本插件演变而来的。
要创建 Gradle 插件,您需要在构建文件之一中编写一个实现Plugin接口的类。
以下示例创建一个GreetingPlugin
,它将hello
任务添加到项目中:
class GreetingPlugin : Plugin<Project> {
override fun apply(project: Project) {
project.task("hello") {
doLast {
println("Hello from the GreetingPlugin")
}
}
}
}
// Apply the plugin
apply<GreetingPlugin>()
class GreetingPlugin implements Plugin<Project> {
void apply(Project project) {
project.task('hello') {
doLast {
println 'Hello from the GreetingPlugin'
}
}
}
}
// Apply the plugin
apply plugin: GreetingPlugin
$ gradle -q hello Hello from the GreetingPlugin
该Project
对象作为参数传递apply()
,插件可以根据需要使用它来配置项目(例如添加任务、配置依赖项等)
脚本插件apply(from = " ")
与构建脚本插件类似,但是,插件定义只是在单独的脚本中完成,然后使用或将其应用于构建文件apply from: ''
:不建议使用脚本插件。
class GreetingScriptPlugin : Plugin<Project> {
override fun apply(project: Project) {
project.task("hi") {
doLast {
println("Hi from the GreetingScriptPlugin")
}
}
}
}
// Apply the plugin
apply<GreetingScriptPlugin>()
class GreetingScriptPlugin implements Plugin<Project> {
void apply(Project project) {
project.task('hi') {
doLast {
println 'Hi from the GreetingScriptPlugin'
}
}
}
}
// Apply the plugin
apply plugin: GreetingScriptPlugin
apply(from = "other.gradle.kts")
apply from: 'other.gradle'
$ gradle -q hi Hi from the GreetingScriptPlugin
预编译脚本插件
预编译脚本插件在执行之前会被编译成类文件并打包成 JAR。这些插件使用 Groovy 或 Kotlin DSL,而不是纯 Java、Kotlin 或 Groovy。它们最好用作跨项目共享构建逻辑的约定插件,或者作为整齐组织构建逻辑的一种方式。
要创建预编译脚本插件,您可以:
-
使用 Gradle 的 Kotlin DSL - 插件是一个
.gradle.kts
文件,并应用id("kotlin-dsl")
. -
使用 Gradle 的 Groovy DSL - 该插件是一个
.gradle
文件,并应用id("groovy-gradle-plugin")
.
要应用预编译脚本插件,您需要知道其ID。 ID 源自插件脚本的文件名及其(可选)包声明。
例如,该脚本src/main/*/java-library.gradle(.kts)
的插件 ID 为java-library
(假设它没有包声明)。同样,只要它的包声明为 ,src/main/*/my/java-library.gradle(.kts)
就有一个插件 ID 。my.java-library
my
预编译脚本插件名称有两个重要的限制:
-
他们不能从 开始
org.gradle
。 -
它们不能与核心插件同名。
当插件应用于项目时,Gradle 会创建插件类的实例并调用该实例的Plugin.apply()方法。
Plugin 在应用该插件的每个项目中都会创建
一个新的 a 实例。 |
让我们将GreetingPlugin
脚本插件重写为预编译脚本插件。由于我们使用的是 Groovy 或 Kotlin DSL,因此该文件本质上成为插件。原始脚本插件只是创建了一个hello
打印问候语的任务,这就是我们将在预编译脚本插件中执行的操作:
tasks.register("hello") {
doLast {
println("Hello from the convention GreetingPlugin")
}
}
tasks.register("hello") {
doLast {
println("Hello from the convention GreetingPlugin")
}
}
GreetingPlugin
现在可以使用其 ID 将其应用到其他子项目的构建中:
plugins {
application
id("GreetingPlugin")
}
plugins {
id 'application'
id('GreetingPlugin')
}
$ gradle -q hello Hello from the convention GreetingPlugin
约定插件
约定插件通常是预编译的脚本插件,它使用您自己的约定(即默认值)配置现有的核心和社区插件,例如使用java.toolchain.languageVersion = JavaLanguageVersion.of(17)
.约定插件还用于执行项目标准并帮助简化构建过程。他们可以应用和配置插件、创建新任务和扩展、设置依赖项等等。
让我们以包含三个子项目的构建为例:一个用于data-model
,一个用于database-logic
,一个用于app
代码。该项目具有以下结构:
.
├── buildSrc
│ ├── src
│ │ └──...
│ └── build.gradle.kts
├── data-model
│ ├── src
│ │ └──...
│ └── build.gradle.kts
├── database-logic
│ ├── src
│ │ └──...
│ └── build.gradle.kts
├── app
│ ├── src
│ │ └──...
│ └── build.gradle.kts
└── settings.gradle.kts
子项目的build文件database-logic
如下:
plugins {
id("java-library")
id("org.jetbrains.kotlin.jvm") version "1.9.23"
}
repositories {
mavenCentral()
}
java {
toolchain.languageVersion.set(JavaLanguageVersion.of(11))
}
tasks.test {
useJUnitPlatform()
}
kotlin {
jvmToolchain(11)
}
// More build logic
plugins {
id 'java-library'
id 'org.jetbrains.kotlin.jvm' version '1.9.23'
}
repositories {
mavenCentral()
}
java {
toolchain.languageVersion.set(JavaLanguageVersion.of(11))
}
tasks.test {
useJUnitPlatform()
}
kotlin {
jvmToolchain {
languageVersion.set(JavaLanguageVersion.of(11))
}
}
// More build logic
我们应用该java-library
插件并添加该org.jetbrains.kotlin.jvm
插件以支持 Kotlin。我们还配置 Kotlin、Java、测试等。
我们的构建文件开始增长......
我们应用的插件越多,配置的插件越多,它就越大。app
和子项目的构建文件中也存在重复data-model
,尤其是在配置常见扩展(例如设置 Java 版本和 Kotlin 支持)时。
为了解决这个问题,我们使用约定插件。这使我们能够避免在每个构建文件中重复配置,并使我们的构建脚本更加简洁和可维护。在约定插件中,我们可以封装任意构建配置或自定义构建逻辑。
要开发约定插件,我们建议使用buildSrc
– 它代表完全独立的 Gradle 构建。
buildSrc
有自己的设置文件来定义此构建的依赖项所在的位置。
my-java-library.gradle.kts
我们在目录中添加一个名为的 Kotlin 脚本buildSrc/src/main/kotlin
。或者相反,在目录my-java-library.gradle
内调用 Groovy 脚本buildSrc/src/main/groovy
。我们将构建文件中的所有插件应用程序和配置放入database-logic
其中:
plugins {
id("java-library")
id("org.jetbrains.kotlin.jvm")
}
repositories {
mavenCentral()
}
java {
toolchain.languageVersion.set(JavaLanguageVersion.of(11))
}
tasks.test {
useJUnitPlatform()
}
kotlin {
jvmToolchain(11)
}
plugins {
id 'java-library'
id 'org.jetbrains.kotlin.jvm'
}
repositories {
mavenCentral()
}
java {
toolchain.languageVersion.set(JavaLanguageVersion.of(11))
}
tasks.test {
useJUnitPlatform()
}
kotlin {
jvmToolchain {
languageVersion.set(JavaLanguageVersion.of(11))
}
}
该文件的名称my-java-library
是我们全新插件的 ID,我们现在可以在所有子项目中使用它。
为什么版本id 'org.jetbrains.kotlin.jvm' 不见了?请参阅将外部插件应用于预编译脚本插件。
|
database-logic
通过删除所有冗余的构建逻辑并应用我们的约定插件,构建文件变得更加简单my-java-library
:
plugins {
id("my-java-library")
}
plugins {
id('my-java-library')
}
这个约定插件使我们能够轻松地在所有构建文件之间共享通用配置。任何修改都可以在一处进行,从而简化了维护。
二进制插件
Gradle 中的二进制插件是作为独立 JAR 文件构建并使用plugins{}
构建脚本中的块应用于项目的插件。
让我们将其转移GreetingPlugin
到一个独立的项目,以便我们可以发布它并与其他人共享。该插件本质上是从该buildSrc
文件夹移动到其自己的名为greeting-plugin
.
您可以从 发布插件buildSrc ,但不建议这样做。准备发布的插件应该是它们自己的版本。
|
greeting-plugin
只是一个生成包含插件类的 JAR 的 Java 项目。
将插件打包并发布到存储库的最简单方法是使用Gradle Plugin Development Plugin。该插件提供了必要的任务和配置(包括插件元数据),将您的脚本编译为可应用于其他版本的插件。
greeting-plugin
这是使用 Gradle Plugin 开发插件的项目的简单构建脚本:
plugins {
`java-gradle-plugin`
}
gradlePlugin {
plugins {
create("simplePlugin") {
id = "org.example.greeting"
implementationClass = "org.example.GreetingPlugin"
}
}
}
plugins {
id 'java-gradle-plugin'
}
gradlePlugin {
plugins {
simplePlugin {
id = 'org.example.greeting'
implementationClass = 'org.example.GreetingPlugin'
}
}
}
有关发布插件的更多信息,请参阅发布插件。
项目 vs 设置 vs 初始化插件
这几种插件的区别在于它们的应用范围:
- 项目插件
-
项目插件是应用于构建中的特定项目的插件。它可以自定义构建逻辑、添加任务以及配置特定于项目的设置。
- 设置插件
-
settings.gradle
设置插件是在或文件中应用的插件settings.gradle.kts
。它可以配置适用于整个构建的设置,例如定义构建中包含哪些项目、配置构建脚本存储库以及将通用配置应用于所有项目。 - 初始化插件
-
init.gradle
init 插件是在或文件中应用的插件init.gradle.kts
。它可以配置全局适用于计算机上所有 Gradle 构建的设置,例如配置 Gradle 版本、设置默认存储库或将通用插件应用于所有构建。