编辑:我将CDI注入点从使用@EJB更改为使用@Inject,如下面的注释中所示。只是一个FYI。
我有两个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,默认是注入,而不是替代。这不是预期的行为。
答案 0 :(得分:4)
beans.xml ,您必须在其中指定替代品, 必须位于 ejb-client.jar 内,而不是 ejb-client-2.jar 。
CDI规范(1.1,但适用于之前的实施)在第5.1章中指出:
替代品不适用于注射,查找或EL分辨率 除非模块是bean,否则模块中的类或JSP / JSF页面 存档和替代是在该bean中明确选择的 档案
换句话说,您必须在使用bean的类的同一模块中选择替代方案。
答案 1 :(得分:3)
对于那些想知道发生了什么的人来说,这会混合CDI和EJB(EE5)注入。这就是第一个错误发生的原因。替代品是CDI的想法,而@EJB不承认它们。
默认而不是替代的原因是因为这是注入时使用的限定符(替代方案没有暗示@Default)。这基本上告诉CDI我确切地知道我想要哪个实例,它是我在注射时使用的具有相同限定符的实例。处理这样的事情的最好方法是简单地使用@Inject而不使用任何限定符,除非你确切知道你想要哪个实例并将这些限定符添加到注入(实现类中的相同)。