Gradle 和插件扩展关闭的执行顺序
Gradle and plugin extension closure order of execution
我有 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 in your tasks, their values are set once they're required. This is the preferred way because it minimizes task configuration, but it can get very confusing, a guide showing how to use properties: Lazy Configuration: connecting properties together虽然它使用Groovy,但应该很容易翻译成Java。
还有一个解决方案,就是添加一个post评估监听器。一旦配置了所有插件和扩展,它就会被调用,但如果多个插件正在配置相同的任务,这可能会变得混乱。请参阅此线程讨论 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 生命周期。
我有 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 in your tasks, their values are set once they're required. This is the preferred way because it minimizes task configuration, but it can get very confusing, a guide showing how to use properties: Lazy Configuration: connecting properties together虽然它使用Groovy,但应该很容易翻译成Java。
还有一个解决方案,就是添加一个post评估监听器。一旦配置了所有插件和扩展,它就会被调用,但如果多个插件正在配置相同的任务,这可能会变得混乱。请参阅此线程讨论 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 生命周期。