【问题标题】:Spring Boot Custom Condition Class and ConfigurationSpring Boot 自定义条件类和配置
【发布时间】:2021-10-21 14:21:26
【问题描述】:

我有一个自定义条件类和一个配置,它有一个基于我的自定义条件类 (MyCondition) 的条件 Bean。问题是我需要从上下文访问另一个 bean 来评估条件,但是这失败了,因为“myBean”需要先加载一些其他配置,所以找不到“myBean”类型的 1 个 bean。总共有 3 个单独的配置要加载,在我引入名为 MyConfiguration 的第三个配置类之前,顺序并不重要。 ConfigurationA 和 ConfigurationB 需要在 MyConfiguration 加载之前加载。问题是在实例化任何其他 bean 之前调用条件,因此即使 MyCondition 中的以下上下文调用获取 bean 名称“myBean”(myBean 在 ConfigurationB 文件中创建)它也会失败,因为它需要来自 ConfigurationA 的另一个 bean .

我已经厌倦了dependsOn、AutoConfigureAfter 的多种组合,但顺序并不相关,因为Spring 固有地尝试在它实例化/创建defaultBeansMap 中的bean 之前加载条件。

ConfigurationA
ConfigurationB

@Configuration
public class MyConfiguration {

 @Bean
 @Condition(MyCondition.class)
 public MyClass createMyClass() {
    return new MyClass()
 }

}

public class MyCondition implements Condition  {    ​
    ​@Override
  ​  public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
   ​  return context.getBeanFactory().getBean("myBean").getName().equals("Artem");
​   }
}

条件只能对加载的属性起作用,而不是对所需的运行时对象(类)的顺序起作用吗?

【问题讨论】:

  • 您是否尝试过将myBean 转换为对MyCondition 的依赖,试图在MyCondition 之前强制创建myBean?过去从未尝试过,但可能值得一试。
  • 但是 mycondition 只是一个类,它本身并不是一个 bean。我也试过了——没用。
  • 是的,你需要把它变成@Component
  • 你试过@ConditionalOnBean 吗?强制先加载你需要的bean。
  • 我已经尝试过,但是将 conditionalOnBean 和 dependsOn 作为 MyCondition 的注释。它不起作用,我看到的问题是 Condition.matches 在 ConditionContext.beanfactory 中的任何bean被初始化之前被评估。因此,即使它们存在于映射中,也没有创建依赖图,也没有初始化 bean。一件奇怪的事情是,MyBean 需要另一个 bean(我们称之为 BeanC)并且它不存在于 beanfactory 映射中,即使我也将它作为 MyBean 的一个依赖项......

标签: java spring spring-boot conditional-statements spring-annotations


【解决方案1】:

根据 -> How to autowire properties bean from Condition

如果我们查看 Condition 接口的 java 文档 -

条件必须遵循与 BeanFactoryPostProcessor 相同的限制,并注意永远不要与 bean 实例交互。

限制是(来自 BeanFactoryPostProcessor 的 java 文档)

BeanFactoryPostProcessor 可以与 bean 定义交互和修改,但不能与 bean 实例交互。这样做可能会导致 bean 过早实例化,违反容器并导致意外的副作用。

因此,不推荐您尝试实现的目标;已经遇到的副作用。

但是,如果我们在文档中进一步挖掘 Condition 我们会得到

要对与@Configuration bean 交互的条件进行更细粒度的控制,请考虑 ConfigurationCondition 接口。

这里也违反了限制。因此,总而言之,在这种情况下使用 Condition 并不是一个好主意。

【讨论】:

    猜你喜欢
    • 2018-12-24
    • 2020-02-02
    • 2020-11-06
    • 2018-12-11
    • 2018-11-14
    • 2018-08-13
    • 1970-01-01
    • 2016-09-08
    • 1970-01-01
    相关资源
    最近更新 更多