【问题标题】:How to make a configuration conditional on another configuration?如何使配置以另一个配置为条件?
【发布时间】:2016-11-25 12:36:36
【问题描述】:

我想让我的 spring-boot 配置类 A 依赖于另一个配置类 B,即只有在评估 B 配置时才会评估 A 配置。

在实际情况下,我有数百个 Ai 配置,只有一个 B,我想实现一种方法,通过在测试期间仅排除 B 来排除所有 Ai 配置。

我尝试了以下方法:

@Configuration
@ConditionalOnBean(type = "org.my.B")
public class A1AutoConfiguration {
// ...
}

其中B 是一个无条件 配置类。

但是当我运行mvn spring-boot:run -Ddebug=true 时,我看到A 从未评估,因为缺少B。虽然在 B 中创建的 bean 在应用程序上下文中,但 B 本身却不在。

虽然我可以使 Ai 配置类依赖于 在内部创建的 bean B,但我不太喜欢这种解决方案。

是否有一种更简洁(且有效)的方式来实现这种依赖机制?

【问题讨论】:

  • 我不明白这里有什么问题,你让所有 Ai 都依赖于 B 并且没有 B,因为你明确排除了 B,所以它们没有被加载。这不是预期的行为吗?你想做什么?
  • 不,他们被排除在外总是,不仅仅是当我禁用B时。

标签: spring-boot


【解决方案1】:

关键是确保正确订购物品。如果您不能确保首先评估 B,则要求 A 仅在 B 存在时才应用是没有任何意义的。

数百部分让我有点害怕。如果 As 和 B 是自动配置的,你可以使用下面的

@AutoconfigureAfter(B.class)
@ConditionalOnBean(B.class)
public class A123AutoConfiguration { ...}

如果 As 和 B 不是自动配置的,您需要确保首先处理 B,这样您就不能依赖常规的类路径扫描。

【讨论】:

  • 谢谢,这在我的情况下有效,但并不总是有效。当A123AutoConfiguration 放在主模块而不是带有“spring.factory”文件的外部模块中时,它无法找到 B 并失败并出现缺少 bean 错误。
  • 如果你愿意,我可以分享一个例子来说明问题。
  • 如果它不在类路径上,您可以使用字符串litteral。但这也很奇怪。如果我误解了它应该在那里,是的,样本会有所帮助
  • A123AutoConfiguration 不是自动配置。这已在此处明确提出。
【解决方案2】:

我会说这样的一组bean适合单独的库或子模块,因此它们是独立的。包括机制可以是对此类库或子模块的根包的组件扫描。

其他选项是使用 Spring 配置文件。用@Profile annotation标记你的bean并使用@ActiveProfiles to enable certain group of beans during test

【讨论】:

    猜你喜欢
    • 2014-10-19
    • 2010-11-02
    • 2014-10-07
    • 2011-12-26
    • 2010-09-18
    • 1970-01-01
    • 2023-03-20
    • 1970-01-01
    • 2022-06-13
    相关资源
    最近更新 更多