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

Boz*_*zho 38 java cdi jboss-weld

比方说,我有一个名为接口SocialNetworkService,以及三种实现- TwitterService,FacebookServiceFriendFeedService.

现在我希望,只要我的托管bean(或任何Web组件)收到消息,就可以在所有社交网络中共享它.我试过了:

@Inject private List<SocialNetworkService> socialNetworkServices;
Run Code Online (Sandbox Code Playgroud)

但它不起作用(部署错误).(也尝试了@Any限定符 - 相同的结果)

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

我知道给定注入点不应该有多个可能的bean的规则.我想我可以通过制作一个生成列表和使用的生产者来实现这一目标Instance<SocialNetworkService>,但这对于这项任务来说似乎太多了.

Boz*_*zho 66

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

@Inject @Any
private Instance<SocialNetworkService> services;
Run Code Online (Sandbox Code Playgroud)

Instance实现Iterable,因此可以简单地使用for-each循环.在@Any需要预选赛.


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

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

    @Inject private Event<MessageEvent> msgEvent;
    
    Run Code Online (Sandbox Code Playgroud)

    解雇它: msgEvent.fire(new MessageEvent(message));

  • 观察所有服务中的事件(无论其界面如何,这可能是一个加号):

    public void consumeMessageEvent(@Observes MessageEvent msgEvent) {..}
    
    Run Code Online (Sandbox Code Playgroud)

  • +1这将进入我的CDI反模式列表! (2认同)
  • 好吧,我认为两者都是有效的.第一种意味着更多的耦合,实际上,但是,例如,稍后更容易追踪.这取决于你的目标. (2认同)