Gradle和plugin扩展的执行顺序

Gradle和plugin扩展的执行顺序,gradle,groovy,closures,gradle-plugin,Gradle,Groovy,Closures,Gradle Plugin,我有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时,一切都按预期工作,这意味着

我有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)始终是延迟配置的

首先,您可以在任务中使用它们,一旦需要它们,就会设置它们的值。这是首选的方法,因为它最小化了任务配置,但可能会变得非常混乱,这是一个演示如何使用属性的指南:尽管它使用Groovy,但它应该很容易翻译成Java

还有另一个解决方案,就是添加一个评估后监听器。一旦配置了所有插件和扩展,就会调用它,但是如果多个插件正在配置相同的任务,这可能会变得混乱。看到这个帖子了吗。另一方面,一些官方的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));
        );
    }
}
类PluginA实现插件{
伸展a;
公开作废申请(项目){
a=project.getExtension().create(“E_a”,ExtensionA.class);
project.getTasks().register(“T_A”);//此处可能未设置prop_A
project.getTasks().findByName(“T_A”).doLast(T->System.out.println(A.prop_A));
项目后评估(p->
//a项目将在此处设置
p、 getTasks().findByName(“T_A”).doLast(T->System.out.println(A.prop_A));
);
}
}
显然,你可以让这更干净


我建议你和听众一起玩,更好地了解Gradle的生命周期。

Gradle团队努力寻找
项目的替代者。评估后
。仍然在v6.x版本中,我们无法摆脱
project.afterEvaluate
))