繁体   English   中英

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

[英]How to Inject @Alternative with CDI from WAR into EJB Module

我想让CDI“选择”替代类作为接口的实现。

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

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

EJB模块:

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模块:

@Alternative
public class D implements I {}

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

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

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

唯一的问题是你错放了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>)

还要记住,虽然对于标准bean,替代选择仅适用于 bean 中的模块,但是在beans.xml声明了替代选择 ,对于EJB来说也是如此。 所以你的D替代品( @Stateless )对整个应用程序都有效。

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

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM