我有3个插件“A”,“B”和“C”。插件“A”包括具有以下内容的插件“B”:
project.getPlugins().apply(B.class);
插件“B”包括具有以下内容的插件“C”:
project.getPlugins().apply(C.class);
总而言之,相关性为:A> B> C
插件“A”具有自定义任务“T_A”和自定义扩展名“E_A”。插件“C”具有自定义扩展名“E_C”。
当我使用以下
build.gradle
并执行gradlew T_A
时,一切都按预期工作,这意味着在执行T_A之前设置了属性:plugins {
id 'A'
}
E_A {
prop_a = 'hello'
}
E_C {
prop_c = 'world'
}
但是,具有以下build.gradle:
plugins {
id 'A'
}
E_C {
prop_c = 'world'
}
E_A {
prop_a = 'hello'
}
...然后,在执行任务之前不会设置prop_a。
我被困住了,真的不明白为什么可能错了。
build.gradle
文件中扩展名的关闭顺序重要吗?
最佳答案
在配置阶段,调用应用函数时,不能保证某些值被设置为。因此,顺序确实很重要,但是依靠顺序是一个坏习惯。复杂的扩展名(例如NamedDomainObjectContainer)总是延迟配置的。
首先,您可以在任务中使用Property,一旦需要就可以设置它们的值。这是首选方法,因为它可以最大程度地 reduce task 配置,但可能会非常困惑,它是显示如何使用属性的指南:Lazy Configuration: connecting properties together尽管它使用Groovy,但应该易于转换成Java。
还有另一种解决方案,即添加评估后的侦听器。一旦配置了所有插件和扩展名,就会调用该方法,但是如果多个插件配置相同的任务,则可能会变得困惑。参见讨论project afterEvaluate usage的线程。在旁注中,某些Gradle官方插件仍按值配置任务。
class PluginA implements Plugin<Project> {
ExtensionA a;
public void apply(Project project) {
a = project.getExtension().create("E_A", ExtensionA.class);
project.getTasks().register("T_A"); //prop_a may not be set here
project.getTasks().findByName("T_A").doLast(t -> System.out.println(a.prop_a));
project.afterEvaluate(p ->
//prop_a will be set here
p.getTasks().findByName("T_A").doLast(t -> System.out.println(a.prop_a));
);
}
}
显然,您可以使它更整洁。
我建议您与听众一起玩,以更好地了解Gradle的生命周期。
关于gradle - Gradle和插件扩展关闭执行顺序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61673427/