3

编辑:我将 CDI 注入点从使用 @EJB 更改为使用 @Inject,如下面的评论所示。仅供参考。


我有两个EAR项目,基本一样。他们唯一的区别是一些客户特定的实现,如果需要的话。但是,我遇到了问题。

这就是我所拥有的:

EAR #1 包含以下模块:

web.war 
ejb-default.jar
ejb-client-1.jar

EAR #2 包含以下模块:

web.war
ejb-default.jar
ejb-client-2.jar

在 ejb-default 中包含以下内容:

@Singleton
@Startup
public class ApplicationSettingsBean implements ApplicationSettingsBeanLocal

现在,对于 EAR #1,ejb-client-1.jar 可能是空的,因此任何 EJB 注入都应该使用 ejb-default 中的任何内容。

然而,对于 EAR #2,我想用特定于客户端的实现来覆盖默认实现。例如:

@Singleton
@Startup    
@Alternative
public class ApplicationSettingsBean implements ApplicationSettingsBeanLocal {

我还在 ejb-client-2 中创建了以下 beans.xml 条目:

<beans xmlns="http://java.sun.com/xml/ns/javaee"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/beans_1_0.xsd">
    <alternatives>
        <class>com.client2.ejb.ApplicationSettingsBean</class>
    </alternatives>
</beans>

我希望@Alternative 实现会在这样的实现存在时被注入。如果在注入点指定了@Default,则应该注入默认实现(ejb-default)。虽然,这不会发生:

    // Inject the alternative implementation
    @Inject
    private ApplicationSettingsBeanLocal appSettingsBean;

使用此 CDI,将注入默认值,而不是替代方案。这不是预期的行为。

4

2 回答 2

4

您必须指定替代项的beans.xml必须在ejb-default.jar中,而不是在ejb-client-2.jar中。

CDI 规范(1.1,但也适用于以前的实现)在第 5.1 章中指出:

替代方案不可用于注入、查找或 EL 解析到模块中的类或 JSP/JSF 页面,除非该模块是 bean 存档并且在该 bean 存档中明确选择了替代方案。

换句话说,您必须在使用该 bean 的类的同一模块中选择替代方案。

于 2014-11-12T09:47:42.350 回答
3

对于那些想知道发生了什么的人,这混合了 CDI 和 EJB (EE5) 注入。这就是发生第一个错误的原因。替代方案是 CDI 想法,@EJB 无法识别它们。

使用默认而不是替代的原因是因为这是在注入中使用的限定符(替代没有隐含@Default)。这实际上告诉 CDI 我确切地知道我想要哪个实例,它是我在注入时使用的具有相同限定符的实例。处理此类事情的最佳方法是简单地使用 @Inject 而不使用任何限定符,除非您确切知道您想要哪个实例并将这些限定符添加到注入中(实现类上的相同)。

于 2012-10-04T22:54:56.917 回答