java 在 CDI(焊接)中注入对象列表
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/4009388/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Inject list of objects in CDI (Weld)
提问by Bozho
Let's say I have an interface called SocialNetworkService, and three implementations - TwitterService, FacebookServiceand FriendFeedService.
假设我有一个名为 的接口SocialNetworkService和三个实现 - TwitterService、FacebookService和FriendFeedService。
Now I want, whenever my managed bean (or whatever web component) receives a message, to share it in all social networks. I tried:
现在我想,每当我的托管 bean(或任何 Web 组件)收到一条消息时,就在所有社交网络中共享它。我试过:
@Inject private List<SocialNetworkService> socialNetworkServices;
But it didn't work (deployment error). (Also tried to the @Anyqualifier - same result)
但它不起作用(部署错误)。(也尝试过@Any预选赛 - 结果相同)
So, is there a way to inject a list of all (or some) implementations of an interface?
那么,有没有办法注入一个接口的所有(或一些)实现的列表?
I know the rule that a given injection point should not have more than one possible bean. I guess I can achieve that by making a producer that produces the list, and using Instance<SocialNetworkService>, but that seems like too much for this task.
我知道给定注入点不应有多个可能的 bean 的规则。我想我可以通过制作一个生成列表的生产者并使用 来实现这一点Instance<SocialNetworkService>,但这对于这项任务来说似乎太多了。
回答by Bozho
Combining my attempts with an answer from the Weld forum:
将我的尝试与 Weld 论坛的答案相结合:
@Inject @Any
private Instance<SocialNetworkService> services;
Instanceimplements Iterable, so it is then possible to simply use the for-each loop. The @Anyqualifier is needed.
Instance实现Iterable,因此可以简单地使用 for-each 循环。在@Any需要预选赛。
Another way to do this is by using the event system:
另一种方法是使用事件系统:
- create a
MessageEvent(containing all the information about the message) instead of injecting a list of social networks, simply inject the event:
@Inject private Event<MessageEvent> msgEvent;and fire it:
msgEvent.fire(new MessageEvent(message));observe the event in all services (regardless of their interface, which might be a plus):
public void consumeMessageEvent(@Observes MessageEvent msgEvent) {..}
- 创建一个
MessageEvent(包含有关消息的所有信息) 无需注入社交网络列表,只需注入事件:
@Inject private Event<MessageEvent> msgEvent;并开火:
msgEvent.fire(new MessageEvent(message));观察所有服务中的事件(不管它们的界面如何,这可能是一个加分项):
public void consumeMessageEvent(@Observes MessageEvent msgEvent) {..}
回答by Thorbj?rn Ravn Andersen
I had a look at the JSR-299 specification and it doesn't seem that you can do what you want to do easily and I do not have experience enough with Weld to provide code for this special case.
我查看了 JSR-299 规范,似乎您无法轻松完成自己想做的事情,而且我对 Weld 的经验不足,无法为这种特殊情况提供代码。
However, based on chapter 12.3 "Bean Discovery" you might be able to declare the implementations as @Alternative's (to avoid Weld complain about multiple implementations) and listen to ProcessBean events to collect when implementations of SocialNetworkService are seen.
但是,根据第 12.3 章“Bean 发现”,您可以将实现声明为 @Alternative(以避免 Weld 抱怨多个实现)并在看到 SocialNetworkService 的实现时收听 ProcessBean 事件以进行收集。

