我必须实现一个实例工厂,它返回一个新的消息处理程序实例,取决于消息代码。
有一个接口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包。它只有messageCodes。
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。
答案 0 :(得分:2)
您可以通过观察ProcessAnnotatedType
获取便携式扩展中的所有实例。将这些存储在侦听器类中的另一个类或静态集合中,然后您可以通过注入类来获取所有这些实例。
另一个选项是将InjectionPoint
注入到您的producer方法中,并使用其中的信息返回Instance
遍历期间所需的实例。但请注意,这仅适用于依赖范围的注入。
答案 1 :(得分:0)
不确定我理解您的功能要求。
听起来像生产者模式是错误的选择,如果你不知道要生产什么,那么为什么选择呢?
我不遵循代码实际执行的操作,但是让我问一下,如果只是拥有接口并进行实现会有什么问题?
每个新实现都获得它自己的限定符,任何上下文实例都可以使用@Inject @QualifierName来获取它。
我实际上认为你可能会无缘无故地做复杂的事情,但我不确定,因为我真的不明白这个问题: - )