0

我必须实现一个实例工厂,它返回一个新的消息处理程序实例,具体取决于消息代码。

有一个接口 MessageHandler 和这个接口的大约 50 个实现。由于项目结构(maven 循环依赖...),工厂类与具体接口实现没有依赖关系。

一个messageHandler接口:

interface MessageHandler {
    void receive(Message message);

    MessageCode getMessageCode();
}

每个 MessageHandler 实现都返回一个唯一的消息代码。例如:

class FirstMessageHandler implements MessageHandler {
     ...
     @Override
     MessageCode getMessageCode(){
          return MessageCodes.MESSAGE_TYPE_ONE;
     }
     ...
}

class SecondMessageHandler implements MessageHandler {
     ...
     @Override
     MessageCode getMessageCode(){
          return MessageCodes.MESSAGE_TYPE_TWO;
     }
     ...
}

MessageHandlerFactory 应该为每条消息创建新的处理程序实例。工厂没有关于具体实现的信息,并且不依赖于实现的 maven 包。它只有消息代码。

class MessagehandlerFactory {
       MessageHandler createHandler(MessageCode messageCode){
       ...
       }
}

搜索后,我找到了一个关于 @Produce 注释的例子和这个很好的例子:

http://docs.oracle.com/javaee/6/tutorial/doc/gkgkv.html

但是在这个例子中,我需要知道工厂中的所有实现类型,这是不允许的。

实际上解决方案是使用@Any @Instance。

 @Inject
 @Any
 private Instance<MessageHandler> messageHandlers;

@PostConstruct
public void init() {
    for (MessageHandler handler : messageHandlers) {
        messageHandlerMap.put(handler.getMessageCodes(), handler);
    }
}

但是此代码为每个接收到的消息的所有 MessageHandler 实现的每个消息实例创建。可以结合@Produce 和@Qualifier 以便根据收到的MessageCode 只创建一个MessageHandler 实例?

我正在使用 Glassfish 3.1.2.2。

4

2 回答 2

2

您可以通过观察来获取可移植扩展中的所有实例ProcessAnnotatedType。将它们存储在另一个类或侦听器类的静态集合中,然后您可以通过注入该类来获取所有这些实例。

另一种选择是将 注入InjectionPoint到您的生产者方法中,并使用那里的信息返回您在Instance遍历期间需要的实例。但是请注意,这仅适用于依赖范围的注入。

于 2013-01-22T14:38:49.610 回答
0

不确定我是否了解您的功能要求。

听起来生产者模式是错误的选择,如果您不知道要生产什么,那么为什么要使用它呢?

我不遵循代码实际上会做什么,但让我问你,仅仅拥有接口并进行实现有什么问题?

每个新实现都有自己的限定符,任何上下文实例都可以使用 @Inject @QualifierName 来获取它。

我实际上认为您可能会无缘无故地做复杂的事情,但我不确定,因为我不太了解这个问题:-)

于 2013-01-21T18:43:06.683 回答