描述
考虑一下当有两个(或更多)Spring配置类时,每种情况都返回一个具有相同名称(例如baseBean
)的bean的情况。另外,假设这些配置类创建其他包含anotherBean1
实例的bean(例如anotherBean2
和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() |
|_______________| |________________|
所有bean必须是单例的,即不是原型。
我强烈怀疑这是不可能的(我检查了Spring在幕后所做的事情,似乎它维护了一个“ bean名称”-> bean实例映射,该映射被首先遇到的任何bean填充。然后,调用截获到Java config方法的代码,并返回已经缓存的bean)因此,确实无法实现我想要的确认。但是我对此也可能是错的...
最佳答案
是否有其他原因baseBean
需要本身是Spring-Managed Bean?
听起来您只是打算从AnotherBean
内部使用它们
因此您只需从@Bean
中删除ConfigX.baseBean()
批注,就可以得到预期的结果。