我有一个spring项目,其中包含一个bean定义文件,其中包含一个bean,它引用另一个bean作为属性,例如
<bean id="aBean" class="org.test.class">
<property class="org.test.A" autowire="byType"/>
</bean>
此bean定义文件将由其他spring项目导入,这些项目可能包含也可能不包含扩展org.test.A的bean。
我想做的是,如果存在org.test.A的扩展实现(即org.test.B),我想在属性中引用它,否则只需引用org.test.A
我一直在研究这个问题,但还没有得到答案。我尝试编写一个自定义的TypeFilter,但这似乎只允许我返回true或false是否应该返回一个类,而不是检查一个类的所有现有bean定义并选择一个。
这样的事情可能吗?如果是这样,怎么会这样做呢?
这个想法是避免必须重写一堆相互引用的bean定义(并且大部分都会在每个项目中都相同)并且只编写引用bean的实现。
对此事的任何意见表示赞赏。
-----更新1 ------
我使用@Primary试了一下,到目前为止没有运气。没有错误,但正在使用的类不是@Primary。
主类org.test.A扩展了另一个类(org.test.Whatever),然后在我的servlet上下文中我有以下内容
<bean id="someID" class="org.someclass">
<property name="realm" ref="testBean" />
</bean>
然后我创建了另一个org.test.B类,它扩展了org.test.A并且同时包含了@Component和@Primary但没有去。 Spring似乎正在加载类但不使用它。
-----更新2 -----
好的,我想我知道发生了什么。我自动装配的类(我无法控制源代码)碰巧有2个set方法,1个接受单个类,1个接受该类的集合。 Spring似乎认为,因为它找到了同一个类的几个bean,它应该自动装配一个集合而不是自动装配一个实例的集合。
如何在我实例化该类的上下文中指定哪个方法应该自动装配?我不明白为什么spring不允许我在属性上使用autowire属性。我只能在bean上设置autowire,它会离开spring来选择自动装配的方法。 :S
答案 0 :(得分:5)
@Primary
注释可能会对您有所帮助。
如果您有多个实施,则使用带@Primary
注释的实施
答案 1 :(得分:0)
您应该使用spring factory method for instantiating this bean。或者,使用查找方法注入,如this示例。
答案 2 :(得分:0)
这是使用SpEL执行此操作的另一种方法 我有两个DataStrategy类型的实现,包含bean ids testDataStrategy和realDataStrategy
我可以通过在Java项目的Property文件中设置属性'data.strategy'来在bean之间进行选择。
<bean id="myBeanId" class="com.some.path.MyBeanClass" >
<property name="dataStrategy" value="# {'${data.strategy}'.equalsIgnoreCase('TEST_DATA') ? testDataStrategy : realDataStrategy}" />
</bean>