4

I want to let CDI "pick up" an Alternative Class as Implementation of an Interface.

While everything is bundles in a EAR the Alternative Implementation will be in the war file and the rest (Class injecting the Interfaces, the Interface, "Default" Implementation of the Interfaces) will be in the ejb jar.

Here some code to illustrate it:

EJB Module:

public interface I {}

 

public class C implements I {}

 

public class A {
  @Inject I var

  public void test() {
    System.out.println(var instanceof C); // I want to have here as Result: false
  }
}

WAR Module:

@Alternative
public class D implements I {}

Setting the beans.xml in the war file did not help..

4

2 回答 2

7

使用您所描述的结构,无法获得所需的注入。

EJB 类加载器将永远无法访问 WAR 中的类,因此注入永远不会考虑替代实现。

如果您愿意更改 EAR 结构,将替代 (D) 与适当的beans.xml. D 类将对您的 EJB 和您的 WAR 可见,并且应该按照需要进行注入。

编辑

我在这里描述的您发布的解决方案几乎可以正常工作。

EAR
  - ejb-module-1.jar 
     - A.class (@Inject I)
     - I.class
     - C.class (@Stateless implements I)
     - META-INF/beans.xml
  - ejb-module-2.jar
     - D.class (@Alternative @Stateless implements I)
     - META-INF/beans.xml (<alternatives><class>D</class></alternative>)
  - app.war
     - calls A.test()
     - WEB-INF/beans.xml

唯一的问题是您放错了beans.xml替代声明。

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

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

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

这是修改后的(和工作的)结构:

EAR
  - ejb-module-1.jar 
     - A.class (@Inject I)
     - I.class
     - C.class (@Stateless implements I)
     - META-INF/beans.xml (<alternatives><class>D</class></alternative>)
  - ejb-module-2.jar
     - D.class (@Alternative @Stateless implements I)
     - META-INF/beans.xml (empty <beans></beans>)
  - app.war
     - calls A.test()
     - WEB-INF/beans.xml (empty <beans></beans>)

还要记住,虽然对于标准 bean,替代选择仅适用于 in 中的模块,替代在 中声明beans.xml,但对于 EJB,情况并非如此。因此,您的D替代方案 (being @Stateless) 对整个应用程序都有效。

于 2013-07-03T21:40:50.773 回答
2

从 CDI 1.1 开始。您可以使用@Priority,以便在全局上下文中发现您的替代方案 - 请参阅此处的依赖注入和编程查找

如果您使用@Priority,则无需在 beans.xml 中声明替代项 - 请参阅此处在 CDI 应用程序中使用替代项

于 2016-06-09T14:15:48.143 回答