如何使用CDI将@Iternative与CDI一起注入EJB模块

Nic*_*ler 4 java ear ejb java-ee cdi

我想让CDI"选择"替代类作为接口的实现.

虽然EAR中的所有内容都是捆绑包,但是替代实现将在war文件中,其余的(类接口,接口,接口的"默认"实现)将在ejb jar中.

这里有一些代码来说明它:

EJB模块:

public interface I {}
Run Code Online (Sandbox Code Playgroud)

 

public class C implements I {}
Run Code Online (Sandbox Code Playgroud)

 

public class A {
  @Inject I var

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

WAR模块:

@Alternative
public class D implements I {}
Run Code Online (Sandbox Code Playgroud)

在war文件中设置beans.xml没有帮助..

Car*_*ini 6

根据您描述的结构,无法获得所需的注射.

EJB类加载器永远不能访问WAR内的类,因此注入永远不会考虑替代实现.

如果您愿意更改EAR结构,将备选方案(D)放在lib/jar中,以及appropriare,则可以采用解决方案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
Run Code Online (Sandbox Code Playgroud)

唯一的问题是你错放了beans.xml备选声明.

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

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

换句话说,您必须在使用该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>)
Run Code Online (Sandbox Code Playgroud)

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