【问题标题】:Gradle and plugin extension closure order of executionGradle 和插件扩展关闭执行顺序
【发布时间】:2020-05-08 06:37:05
【问题描述】:

我有 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 文件中扩展的关闭顺序重要吗?

【问题讨论】:

    标签: gradle groovy closures gradle-plugin


    【解决方案1】:

    在配置阶段,当您的应用函数被调用时,一些值不能保证被设置。所以顺序确实很重要,但依赖它是一种不好的做法。复杂的扩展,例如 NamedDomainObjectContainer 总是延迟配置。

    首先,您可以在任务中使用Property,它们的值在需要时设置。这是首选方式,因为它最大限度地减少了任务配置,但它可能会变得非常混乱,显示如何使用属性的指南: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 团队努力寻找 project.afterEvaluate 的替代品。仍然在 v6.x 的那一刻,我们无法摆脱 project.afterEvaluate ))
    猜你喜欢
    • 2016-02-20
    • 2012-03-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多