首页 > 解决方案 > Gradle:任务配置方法之间的任何区别

问题描述

以下两段代码之间有什么区别吗?
任务的急切初始化可能有一些不同吗?

tasks.bootJar {
    archiveFileName = "some-name"
}

bootJar {
    archiveFileName = "some-code"
}

标签: gradlegroovytask

解决方案


它们实际上是相同的,只是语法不同。两者都会导致任务被实现或急切初始化。您可以通过简单地运行调试输出来确认这一点:./gradlew -d

您将看到记录了以下行:

[调试] [org.gradle.internal.operations.DefaultBuildOperationRunner] 构建操作“实现任务:bootJar”开始

对于 Groovy DSL,Gradle 团队利用 Groovy 语言提供的元编程来动态地使任务、扩展、属性等更“神奇”地可用。

所以对于这个例子:

tasks.bootJar {
    archiveFileName = "some-name"
}

tasks是类型TaskContainer。如果您要检查 的所有可用方法和属性TaskContainer,您会发现这bootJar不是其中之一。所以Gradle挂钩到 Groovy 元编程来搜索名为bootJar. 由于它在TaskContainer类型上,因此可以假设这bootJar是一项任务。

因此,如果您要对 DSL 进行脱糖,第一个示例实际上是:

tasks.getByName("bootJar") {

}

现在来看第二个例子:

bootJar {
    archiveFileName = "some-code"
}

Gradle 构建文件中的默认范围thisProject. 同样,就像以前一样,如果您要检查所有可用的方法和属性,您将不会将bootJar其视为其中之一。

Groovy 的“魔力”在这里发挥了作用,但这一次,Gradle 将几乎在任何地方搜索(我的理解),因为Project.

project.extensions.named("bootJar") // exists?
project.hasProperty("bootJar") // exists?
project.tasks.getByName("bootJar") // found it!

总而言之,两者之间没有区别,因为两者都导致bootJar任务得以实现。尽可能避免使用任务配置来提高 Gradle 构建效率:

import org.springframework.boot.gradle.tasks.bundling.BootJar

tasks.named("bootJar", BootJar) {
    
}

推荐阅读