Jakarta ee 结合@product和@Qualifier的动态对象创建
我必须实现一个实例工厂,它根据消息代码返回一个新的消息处理程序实例 有一个接口MessageHandler和该接口的大约50个实现。由于项目结构(maven循环依赖项…)的原因,factory类对具体的接口实现没有依赖项 messageHandler接口: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实现都返回
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和本文: