强制Spring使用来自相同配置类的bean

时间:2017-08-21 21:08:00

标签: java spring dependency-injection spring-java-config

描述

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

有没有办法让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()  |
  |_______________|     |________________|
  • 所有豆子都需要单身,即不是原型。
  • 我强烈怀疑这是不可能的(我检查了Spring的内幕,它似乎保留了一个" bean名称" - > bean实例映射,其中填充了任何一个bean首先遇到。然后,拦截对Java配置方法的调用,并返回已经缓存的bean)所以确认,我想要的确实不可能,也是一个有效的答案。但我也错了......

1 个答案:

答案 0 :(得分:2)

是否有理由认为不同的@Bean需要是Spring-Managed Beans本身?

听起来你只是计划在ConfigX.baseBean()内使用它们 因此,您只需从<iframe>删除<iframe>注释即可获得预期结果。