Gradle和插件扩展关闭的执行顺序

问题描述 投票:0回答:1

我有3个插件'A', 'B' 和 'C'. 插件'A' 包括插件'B':

project.getPlugins().apply(B.class);

插件B包含了插件C:

project.getPlugins().apply(C.class);

总结一下,这些依赖关系是: A > B > C A > B > C

插件'A'有一个自定义任务'T_A',和一个自定义扩展'E_A'。插件'C'有一个自定义的扩展'E_C'。

当我使用以下内容时 build.gradle 并执行 gradlew T_A在执行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 文件重要吗?

gradle groovy closures gradle-plugin
1个回答
0
投票

在配置阶段,当你的apply函数被调用时,一些 值不保证被设置. 所以,顺序确实很重要,但依赖它是一种不好的做法。复杂的扩展,比如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));
        );
    }
}

很明显,你可以把这个做得更干净。

我建议你玩玩听筒,以便更好地了解Gradle的生命周期。

© www.soinside.com 2019 - 2024. All rights reserved.