jakarta-ee - EJB 的 CDI 生产者

标签 jakarta-ee jboss ejb cdi wildfly

我尝试使用 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 子句,问题就会消失:有人可以解释一下我的类层次结构有什么问题吗?

最佳答案

引用specification

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/

相关文章:

在 EJB 中重新启动 Windows 后出现 javax.naming.NameNotFoundException

netbeans - 创建 session bean 时出错

java - JPA 中的@Any 等价于什么?

java - j2ee : I have a problem regarding jboss server

jboss - 在 JBoss 中实现 CORBA 接口(interface)

java - GarbageCollectionNotificationInfo 使用 Wildfly 8 导致 NoClassDefFoundError

Java EE 安装程序在 Mac OS X Mavericks 上崩溃

java - ImageIO.write 权限被拒绝问题 Ubuntu Java

jakarta-ee - 为什么是无状态 session bean?

java - 在 Glassfish 4 上运行的 EJB 无状态 bean 的 JNDI 查找