我尝试使用 POJO 作为 CDI 生成器来注入(inject)正确的 EJB,但我得到 org.jboss.weld.exceptions.UnsatisfiedResolutionException: WELD-001308。
这是我的制作人 POJO
public class STGatewayUtilProducer {
@Produces
@Chosen
public ISTGatewayUtil getISTGatewayUtil(Instance<STGatewayWSUtil> ws, Instance<STGatewayMQTTUtil> mqtt, ConfigurationManager cm) {
switch(cm.getGatewayProtocol()) {
case ConfigurationManager.GATEWAY_PROTOCOL_TYPE_MQTT:
return mqtt.get();
default:
return ws.get();
}
}
}
这是限定符定义:
@Qualifier
@Target({ TYPE, METHOD, PARAMETER, FIELD })
@Retention(RUNTIME)
@Documented
public @interface Chosen {}
这些是 EJB 声明:
@Stateless
public class STGatewayMQTTUtil implements Serializable, ISTGatewayUtil {
...
}
@Stateless
public class STGatewayWSUtil implements Serializable, ISTGatewayUtil {
...
}
最后,这就是我注入(inject) EJB 的方式:
@Inject
@Chosen
private Instance<ISTGatewayUtil> gtwUtil;
我在使用 JBoss AS 7 和 WildFly 10 时都面临这个问题。
编辑
我找到了问题的核心!我声明了一个通用的抽象父类,它实现了 ejb 接口(interface)并让我的 session bean 扩展它:使用此结构无法解析 bean。
相反,如果我在 session bean 上移动 implements
子句,问题就会消失:有人可以解释一下我的类层次结构有什么问题吗?
最佳答案
3.2.2. Bean types of a session bean
The unrestricted set of bean types for a session bean contains all local interfaces of the bean and their superinterfaces. If the session bean has a no-interface view, the unrestricted set of bean types contains the bean class and all superclasses. In addition, java.lang.Object is a bean type of every session bean.
Remote interfaces are not included in the set of bean types.
因此,由于两个 session bean 都有本地接口(interface),因此它们的 bean 类型集中没有自己的类。因此,您无法用它们的类来解决它们是正常的。
您需要向 session bean 定义添加额外的信息,以便能够区分它们或使用 @LocalBean 注释将它们声明为无接口(interface) View EJB。
这是代码的新版本,将 EJB 声明为 NIV
@Stateless
@LocalBean
public class STGatewayMQTTUtil implements Serializable, ISTGatewayUtil {
...
}
@Stateless
@LocalBean
public class STGatewayWSUtil implements Serializable, ISTGatewayUtil {
...
}
你的生产者不需要注入(inject) 2 Instances<T>
。您可以注入(inject)两个 bean 并返回所选的一个。
public class STGatewayUtilProducer {
@Produces
@Chosen
public ISTGatewayUtil getISTGatewayUtil(STGatewayWSUtil ws, STGatewayMQTTUtil mqtt, ConfigurationManager cm) {
switch(cm.getGatewayProtocol()) {
case ConfigurationManager.GATEWAY_PROTOCOL_TYPE_MQTT:
return mqtt;
default:
return ws;
}
}
}
或使用 Instance<T>
像这样
public class STGatewayUtilProducer {
@Produces
@Chosen
public ISTGatewayUtil getISTGatewayUtil(Instance<ISTGatewayUtil> gw, ConfigurationManager cm) {
switch(cm.getGatewayProtocol()) {
case ConfigurationManager.GATEWAY_PROTOCOL_TYPE_MQTT:
return gw.select(STGatewayMQTTUtil.class).get();
default:
return gw.select(STGatewayWSUtil.class).get();
}
}
}
使用 bean 实例生成新 bean 时要小心,它应该具有 @Dependent
范围(以避免在生成的 bean 上叠加 2 个生命周期)或注入(inject) @New
关键词。您的 session bean 位于 @Dependent
范围,因为它们没有指定任何范围。
关于jakarta-ee - EJB 的 CDI 生产者,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35483011/