我正在查看Mainak Mitra掌握Gradle Gradle构建文件中的自定义任务的简单示例(第70页)。构建脚本是:
println "Working on custom task in build script"
class SampleTask extends DefaultTask {
String systemName = "DefaultMachineName"
String systemGroup = "DefaultSystemGroup"
@TaskAction
def action1() {
println "System Name is "+systemName+" and group is "+systemGroup
}
@TaskAction
def action2() {
println 'Adding multiple actions for refactoring'
}
}
task hello(type: SampleTask)
hello {
systemName='MyDevelopmentMachine'
systemGroup='Development'
}
hello.doFirst {println "Executing first statement "}
hello.doLast {println "Executing last statement "}
如果我使用gradle -q:hello运行构建脚本,则输出为:
Executing first statement
System Name is MyDevelopmentMachine and group is Development
Adding multiple actions for refactoring
Executing last statement
正如预期的那样首先执行doFirst方法,两个自定义操作按照定义的顺序执行,然后执行doLast操作。如果我注释掉添加doFirst和doLast操作的行,则输出为:
Adding multiple actions for refactoring
System Name is MyDevelopmentMachine and group is Development
自定义操作现在按照定义它们的相反顺序执行。我不确定为什么。
答案 0 :(得分:2)
我认为这只是一种情况,即排序不是确定性的,并且根据您进一步配置任务的方式得到不同的结果。
为什么你需要2个独立的@TaskAction方法而不是一个以确定性序列调用方法的方法呢?我无法想到以这种方式做到这一点的特殊优势(我意识到它来自书中给出的样本)。 我找到的大多数其他样本只有一种方法
@TaskAction
void execute() {...}
我认为这更有意义,也更容易预测。
答案 1 :(得分:0)
Patrice M. 是正确的,这些方法的执行方式是不确定的。
详细
@TaskAction 带注释的方法正在由 AnnotationProcessingTaskFactory 处理。
但是第一个任务操作方法是使用 DefaultTaskClassInfoStore 获取的,结果存储在 TaskClassInfo 中。
您可以看到 Class.getDeclaredMethods() 正在用于获取所有方法以检查它们是否包含@TaskAction 注解
这里是public Method[] getDeclaredMethods() throws SecurityException的定义
描述包含以下注释:
<块引用>返回数组中的元素没有排序,不属于任何 特定顺序。
链接到 Gradle discussion forum with the topic about @TaskAction