按类型弹出列表bean
在Spring中是否有一种方法可以使用类型及其任何子类型的所有bean自动填充列表? 我有一个setter方法,如下所示:
setMyProp(List list)
我想在MyType的任何bean和MyType的所有子类中自动assembly。
谢谢,杰夫
是的,你可以做到这一点。 spring的文档说:
通过将注释添加到需要该类型数组的字段或方法,也可以从ApplicationContext提供特定类型的所有bean。
请注意,它表示您需要一个数组,而不是一个列表。 这是有道理的,因为generics类型擦除意味着列表可能无法在运行时工作。 但是,请进行以下unit testing:
而这个unit testing:
package test; @ContextConfiguration @RunWith(SpringJUnit4ClassRunner.class) public class Test { private @Autowired List 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 {} }
所以正式,你应该自动assemblyTypeA[]
,而不是List
,但List工作正常。
如果从应用程序代码中填充列表是可以接受的,而不是从bean定义文件中填充,则可以使用org.springframework.beans.factory.xml.XmlBeanFactory
并将其getBeansOfType( MyType.class )
为“ getBeansOfType( MyType.class )
”。 这将为您提供MyType
类型(和子类型)的所有bean。
如果你可以在代码中使用@Autowired
来填充,你可以安全地使用skaffman提到的方式。 如果您坚持使用XML配置,那么有一个名为Hera的小型库可以实现这一目标。 您描述的场景的基本配置如下所示:
这会将实现SuperType
作为List
所有顶级Spring bean注入客户端bean。
简答:不。
长答案:Javagenerics按类型擦除工作,这意味着在运行时该参数只是一个List,而不是generics类型的List。 因此,您无法弄清楚它的参数类型是MyType,因此无法实现此行为。
话虽如此,还有其他方法可以做到这一点。 最明显的似乎是监听bean创建,然后查看它们是否属于MyType(或子类),然后保留引用。
可能有几种方法可以做到这一点。 一个是创建一个bean后处理器 。 这样,您将收到所有创建的bean的通知。
由于遗留代码和丢失@Autowired,我解决它:
MyBean implements ApplicationContextAware{ @Override public void setApplicationContext(ApplicationContext ctx) throws BeansException { final Map beansOfType = ctx.getBeansOfType(RequiredBean.class); ... }