题
是否有春天有个办法,我可以自动填充与所有A型和其任何亚型的Bean的列表?我有setter方法,看起来像:
setMyProp(List<MyType> list)
和我想的MyType的任何豆类和的MyType的所有子类自动装配。
谢谢, 杰夫
解决方案
是的,你可以做到这一点。弹簧文档说:
另外,也可以提供所有 从特定类型的豆 通过增加的ApplicationContext 注释字段或方法,其 期望类型的数组。
请注意,它说你需要期待一个数组,而不是一个列表。这是有道理的,因为泛型类型擦除意味着列表可以在运行时不工作。然而,采取以下的单元测试,其工作方式:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">
<bean class="test.Test.TypeB"/>
<bean class="test.Test.TypeC"/>
<bean class="test.Test.TypeD"/>
</beans>
和这个单元测试:
package test;
@ContextConfiguration
@RunWith(SpringJUnit4ClassRunner.class)
public class Test {
private @Autowired List<TypeA> beans;
@org.junit.Test
public void test() {
assertNotNull(beans);
assertEquals(2, beans.size());
for (TypeA bean : beans) {
assertTrue(bean instanceof TypeA);
}
}
public static interface TypeA {}
public static class TypeB implements TypeA {}
public static class TypeC extends TypeB {}
public static class TypeD {}
}
那么正式,你应该自动装配TypeA[]
,不List<TypeA>
,但名单做工不错。
其他提示
如果它是可以接受的,从您的应用程序代码填充列表,而不是从bean定义文件中您可以使用org.springframework.beans.factory.xml.XmlBeanFactory
,并要求它“getBeansOfType( MyType.class )
”。这给你MyType
的类型(和子类型)的所有豆。
如果您可以使用@Autowired
里面的代码来填充你可以安全地使用由skaffman提到的方式。如果你坚持XML结构中,有一个名为赫拉实现这个小型图书馆。由您所描述的场景的Esentially配置是这样的:
<bean id="client" class="..">
<property name="injectDynamicListHere">
<hera:list class="my.custom.SuperType" />
</property>
</bean>
此将注入所有顶层弹簧豆实施SuperType
作为List
到客户端豆。
短的答案:没有
龙答:Java泛型按类型删除工作,这意味着在运行时该参数是一个简单的列表,而不是一个泛型类型的列表。因此你不能弄清楚,它意味着是参数类型MyType的,因此它不会是可能实现这一行为。
这就是说,有这样的替代方式。最明显的似乎是侦听bean创建,然后看到它们是否MyType的(或亚类),然后保持的参考。
有可能是几个方法可以做到这一点。一个是创建bean后置处理器。这样,你就会收到通知时创建的每个bean的。
由于遗留代码和遗漏@Autowired我解决它喜欢:
MyBean implements ApplicationContextAware{
@Override
public void setApplicationContext(ApplicationContext ctx) throws BeansException {
final Map<String, HttpRequestHandlerTemplate> beansOfType = ctx.getBeansOfType(RequiredBean.class);
...
}