描述

考虑一下当有两个(或更多)Spring配置类时,每种情况都返回一个具有相同名称(例如baseBean)的bean的情况。另外,假设这些配置类创建其他包含anotherBean1实例的bean(例如anotherBean2baseBean)。

有没有办法让Spring注入在同一配置类中创建的baseBean实例?



// Beans
public abstract class BaseBean {
    public abstract String getName();
}

public class Bean1 extends BaseBean {
    @Override
    public String getName() {
        return "Bean1";
    }
}

public class Bean2 extends BaseBean {
    @Override
    public String getName() {
        return "Bean2";
    }
}

// Configurations
@Configuration
public class Config1 {

    @Bean
    public BaseBean baseBean() {
        return new Bean1();
    }

    @Bean
    public AnotherBean anotherBean1() {
        return new AnotherBean(baseBean());
    }

}

@Configuration
public class Config2 {

    @Bean
    public BaseBean baseBean() {
        return new Bean2();
    }

    @Bean
    public AnotherBean anotherBean2() {
        return new AnotherBean(baseBean());
    }
}

// Main class
public class Main {

    public static void main(String [] args) {
        ApplicationContext applicationContext = new AnnotationConfigApplicationContext(Config1.class, Config2.class);

        AnotherBean anotherBean1 = (AnotherBean) applicationContext.getBean("anotherBean1");
        AnotherBean anotherBean2 = (AnotherBean) applicationContext.getBean("anotherBean2");

        System.out.println(anotherBean1.baseBean.getName());
        System.out.println(anotherBean2.baseBean.getName());
    }
}


预期产量:

Bean1
Bean2


实际输出:

Bean2
Bean2


换句话说,Config1.anotherBean1()Config2.anotherBean2()都调用Config2.baseBean()。相反,我希望每个Config类都调用自己的baseBean方法,即Config1.anotherBean1()应该使用Config1.baseBean()(而Config2.anotherBean2()当然应该使用Config2.baseBean())。

是否有内置方式以某种方式强制执行此行为,例如带有一些注释?

备注


“内置”是指我不想编写BeanPostProcessor或其他类似的扩展名。我想添加一个已经存在的注释或一些类似的解决方案。
添加@Primary@Qualifier等不是一种选择:虽然在上面的示例中可以使用,但是具体的代码以这种方式构造,因此无法实现。更准确地说,baseBean()是抽象基类中的抽象方法,该方法由同一抽象类中的另一个方法anotherBean()调用。然后,具体类为baseBean方法提供实现。这意味着,在基类中,我显然不能使用任何限定符来引用baseBean(并且也不能使任何实现@Primary)。




public class BaseConfig {
       @Bean
       public abstract BaseBean baseBean();

       @Bean
       public AnotherBean anotherBean() {
              return new AnotherBean(baseBean());
       }
}

          +----------------------------+
          |   BaseConfig               |
          |                            |
          | + (abstract) baseBean()    |
          | + anotherBean()            |
          |____________________________|
                    /\
                   /__\
           _________|__________
   _______|_______      _______|__________
  |    Config1    |     |    Config2     |
  | + baseBean()  |     |  + baseBean()  |
  |_______________|     |________________|



所有bean必须是单例的,即不是原型。
我强烈怀疑这是不可能的(我检查了Spring在幕后所做的事情,似乎它维护了一个“ bean名称”-> bean实例映射,该映射被首先遇到的任何bean填充。然后,调用截获到Java config方法的代码,并返回已经缓存的bean)因此,确实无法实现我想要的确认。但是我对此也可能是错的...

最佳答案

是否有其他原因baseBean需要本身是Spring-Managed Bean?

听起来您只是打算从AnotherBean内部使用它们
因此您只需从@Bean中删除​​ConfigX.baseBean()批注,就可以得到预期的结果。

08-05 06:52