【问题标题】:How to select between different CDI-bean implementations runtime如何在不同的 CDI-bean 实现运行时之间进行选择
【发布时间】:2012-12-05 14:33:15
【问题描述】:

我有一个messageListener,目的是启动客户端实现客户端接口。客户端接口的不同实现在编译时是未知的。

messageListener 使用 Launcher-bean 来启动客户端。所以我的问题是我需要构建一个 Launcher-bean,其中注入了客户端接口的选定实现。我不知道该怎么做,还是我应该以不同的方式处理这个问题?

public class MyMessageConsumer implements MessageListener {
    public void onMessage(Message message) {
        String clientType = message.getClientType();

        //Here i need to construct a launcher-bean, which has the correct Client-implementation injected

        launcher.startClient(message);
    }   
}

public class Launcher {

    @Inject
    private Client client;

    public void startClient(Message message) {
        ...

        client.start(message);
    }

}

编辑:我意识到棘手的部分不是找到正确的实现,而是我需要消息的消费作为新请求发生。能不能看懂我在追求什么?

【问题讨论】:

  • 如果您有少量的Client 实现,您可以将它们全部注入您的监听器,选择正确的实现并将其传递给Launcher 构造函数。或者你甚至可以将它作为第二个参数传递给startClient 方法
  • 既然你这么说,那是显而易见的。从来没有想过让听众管理。应该很简单。
  • 但是当我仔细考虑它时,真正的问题是我只有一个 MessageListener 实例(所以我想这会使其成为@ApplicationScoped)。但是每次启动客户端时,我都需要新的客户端实例。所以我想那些范围较小(请求或会话)
  • 如果你想在请求之间重用客户端实例并且每次启动客户端时都有一个唯一的实例,那么它应该是会话范围

标签: java inversion-of-control cdi jboss-weld


【解决方案1】:

你想要的是制作人。

通过这种方式,您可以将上下文实例的客户端和生产者分开。因此,将它们注入生产者并让它决定使用什么。

为了使其透明并避免模棱两可的依赖性,您可以使用 @Dynamic 限定符生成一个值。

@Inject
@Dynamic
Foo foo;

..................

@Produces
@Dynamic
public Foo getFoo() {
//find out what implementation to use and return it  

创建自己的限定符和生产者对 google 来说非常简单。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-07-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-11-07
    • 1970-01-01
    相关资源
    最近更新 更多