在 CDI 中注入对象列表(焊接)

发布于 2024-09-28 16:30:16 字数 535 浏览 3 评论 0原文

假设我有一个名为 SocialNetworkService 的接口,以及三个实现 - TwitterServiceFacebookServiceFriendFeedService

现在我希望,每当我的托管 bean(或任何 Web 组件)收到消息时,都可以在所有社交网络中共享它。我尝试过:

@Inject private List<SocialNetworkService> socialNetworkServices;

但没有成功(部署错误)。 (还尝试了 @Any 限定符 - 相同的结果)

那么,有没有办法注入接口的所有(或某些)实现的列表?

我知道一个规则,即给定的注入点不应有超过一个可能的 bean。我想我可以通过创建一个生成列表的生产者并使用 Instance来实现这一点,但这对于这项任务来说似乎太多了。

Let's say I have an interface called SocialNetworkService, and three implementations - TwitterService, FacebookService and FriendFeedService.

Now I want, whenever my managed bean (or whatever web component) receives a message, to share it in all social networks. I tried:

@Inject private List<SocialNetworkService> socialNetworkServices;

But it didn't work (deployment error). (Also tried to the @Any qualifier - same result)

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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

阳光下的泡沫是彩色的 2024-10-05 16:30:16

将我的尝试与 Weld 论坛的答案结合起来:

@Inject @Any
private Instance<SocialNetworkService> services;

Instance 实现了 Iterable,因此可以简单地使用 for-each 循环。需要 @Any 限定符。


另一种方法是使用事件系统:

  • 创建一个 MessageEvent (包含有关消息的所有信息)
  • 而不是注入社交网络列表,只需注入事件:

    @Inject 私有事件消息事件;
    

    并触发它:msgEvent.fire(new MessageEvent(message));

  • 观察所有服务中的事件(无论其接口如何,这可能是一个优点):

    public void ConsumerMessageEvent(@Observes MessageEvent msgEvent) {..}
    

Combining my attempts with an answer from the Weld forum:

@Inject @Any
private Instance<SocialNetworkService> services;

Instance implements Iterable, so it is then possible to simply use the for-each loop. The @Any qualifier is needed.


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) {..}
    
摇划花蜜的午后 2024-10-05 16:30:16

我查看了 JSR-299 规范,似乎您无法轻松完成您想做的事情,而且我没有足够的 Weld 经验来为这种特殊情况提供代码。

然而,根据第 12.3 章“Bean 发现”,您可能能够将实现声明为 @Alternative(以避免 Weld 抱怨多个实现)并监听 ProcessBean 事件以在看到 SocialNetworkService 的实现时进行收集。

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.

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文