Spring 按类型列出 Bean
Spring 有没有一种方法可以自动填充一个列表,其中包含某个类型的所有 bean 及其任何子类型?我有一个如下所示的 setter 方法:
setMyProp(List<MyType> list)
我想在 MyType 的任何 beans 和 MyType 的所有子类中自动装配。
谢谢, 杰夫
Is there a way in Spring that I can auto populate a list with all of beans of a type AND any of its subtypes? I have a setter method that looks like:
setMyProp(List<MyType> list)
And I would like to autowire in any beans of MyType and all subclasses of MyType.
Thanks,
Jeff
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
是的,你可以这样做。 spring 文档说:
请注意,它表示您需要期待一个数组,而不是一个列表。这是有道理的,因为泛型类型擦除意味着列表在运行时可能不起作用。但是,进行以下有效的单元测试:
以及此单元测试:
因此,正式而言,您应该自动装配
TypeA[]
,而不是List
,而是该列表效果很好。Yup, you can do this. The spring docs say:
Note that it says you need to expect an array, not a list. This makes sense, because generic type erasure means a list may not work at runtime. However, take the following unit test, which works:
and this unit test:
So officially, you're supposed to autowire
TypeA[]
, notList<TypeA>
, but the List works good.如果可以接受从应用程序代码而不是从 bean 定义文件中填充列表,您可以使用 org.springframework.beans.factory.xml.XmlBeanFactory 并询问它“getBeansOfType( MyType.class )”。这将为您提供
MyType
类型(和子类型)的所有 bean。If it's acceptable to fill the list from your application code and not from within the bean definition file you could use the
org.springframework.beans.factory.xml.XmlBeanFactory
and ask it "getBeansOfType( MyType.class )
". This gives you all beans of type (and subtype) ofMyType
.如果您可以在要填充的代码中使用
@Autowired
,您就可以安全地使用 skaffman 提到的方式。如果您坚持使用 XML 配置,可以使用一个名为 Hera 的小型库来实现此目的。您所描述的场景的配置基本上如下所示:这会将所有实现
SuperType
作为List
的顶级 Spring beans 注入到客户端 bean 中。If you can use
@Autowired
inside the code to be populated you can safely use the way mentioned by skaffman. If you insist on XML configuration there is a small library called Hera to achieve this. Esentially configuration of a scenario described by you looks like this:This will inject all top-level Spring beans implementing
SuperType
asList
into the client bean.简短的回答:不。
长答案:Java泛型通过类型擦除来工作,这意味着在运行时该参数只是一个列表,而不是泛型类型的列表。因此,您无法弄清楚它的参数类型是 MyType,因此不可能实现此行为。
话虽如此,还有其他方法可以做到这一点。最明显的似乎是监听 bean 创建,然后查看它们是否属于 MyType(或子类),然后保留引用。
可能有几种方法可以做到这一点。一是创建一个bean后处理器。这样您就会收到创建的每个 bean 的通知。
Short answer: no.
Long answer: Java generics work by type erasure, meaning that at runtime that parameter is simply a List, not a List of a generic type. As such you can't figure out that it is meant to be of parameter type MyType so it wouldn't be possible to implement this behaviour.
That being said, there are alternative ways of doing this. The most obvious seems to be to listen for bean creation and then seeing if they are of MyType (or subclasses) and then keeping a reference.
There is probably a few ways to do this. One is creating a bean post-processor. This way you'll get notified of every bean that's created.
由于遗留代码和缺少@Autowired,我解决它的方式如下:
Due to legacy code and missing @Autowired I solve it like: