Jakarta ee 结合@product和@Qualifier的动态对象创建

Jakarta ee 结合@product和@Qualifier的动态对象创建,jakarta-ee,glassfish,cdi,Jakarta Ee,Glassfish,Cdi,我必须实现一个实例工厂,它根据消息代码返回一个新的消息处理程序实例 有一个接口MessageHandler和该接口的大约50个实现。由于项目结构(maven循环依赖项…)的原因,factory类对具体的接口实现没有依赖项 messageHandler接口: interface MessageHandler { void receive(Message message); MessageCode getMessageCode(); } 每个MessageHandler实现都返回

我必须实现一个实例工厂,它根据消息代码返回一个新的消息处理程序实例

有一个接口MessageHandler和该接口的大约50个实现。由于项目结构(maven循环依赖项…)的原因,factory类对具体的接口实现没有依赖项

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){
       ...
       }
}
搜索之后,我找到了一个关于@product annotation的示例,这个很好的示例:

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

实际上,解决方案是使用@Any@实例

 @Inject
 @Any
 private Instance<MessageHandler> messageHandlers;

@PostConstruct
public void init() {
    for (MessageHandler handler : messageHandlers) {
        messageHandlerMap.put(handler.getMessageCodes(), handler);
    }
}
@Inject
@任何
私有实例消息处理程序;
@施工后
公共void init(){
for(MessageHandler:messageHandlers){
messageHandlerMap.put(handler.getMessageCodes(),handler);
}
}
但是,这段代码为每个消息创建每个接收消息的所有MessageHandler实现的实例。 是否可以结合@product和@Qualifier,以便根据收到的MessageCode只创建一个MessageHandler实例


我使用的是Glassfish 3.1.2.2。

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

听起来制作人模式是个错误的选择,如果你不知道该制作什么,为什么要这么做

我不明白代码实际会做什么,但让我问一下,仅仅拥有接口并进行实现有什么错

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


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

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


另一个选项是将
InjectionPoint
注入到producer方法中,并使用其中的信息在
实例
遍历期间返回所需的实例。但是,请注意,这只适用于依赖范围的注入

谢谢您的回答,问题是:工厂对具体实现没有依赖性。我已经编辑了这个问题。谢谢你的回答。但对于这两种解决方案(ProcessAnnotatedType和InjectionPoint的使用),我都需要一个实例列表。这意味着我将为每条消息创建许多我不需要的对象。有了JSE,我会写这样的东西:MessageHandler product(MessageCode MessageCode){if(MessageCodes.equals(MessageCodes.MESSAGE_TYPE_ONE)){return Class.forName(“FirstMessageHandler”).newInstance();}}我正在寻找更好的CDI替代解决方案:)为什么需要实例列表?这些消息处理程序本身需要注射吗?谢谢,我又读了一遍weld docu并找到了正确的解决方案。我使用了InjectionPoint和本文: