java - 如何将带有 CDI 的 @Alternative 从 WAR 注入(inject)到 EJB 模块中

标签 java jakarta-ee ejb cdi ear

我想让 CDI“挑选”一个替代类作为接口(interface)的实现。

虽然 EAR 中的所有内容都是 bundle ,但替代实现将在 war 文件中,其余部分(注入(inject)接口(interface)的类、接口(interface)、接口(interface)的“默认”实现)将在 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 没有帮助..

最佳答案

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

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

如果您愿意更改 EAR 结构,将备选方案 (D) 与适当的 beans.xml 一起放置在 lib/jar 中,那么一个解决方案是可能的。 D 类将对您的 EJB 和 WAR 可见,并且注入(inject)应按需要进行。

编辑

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

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 章指出:

An alternative is not available for injection, lookup or EL resolution to classes or JSP/JSF pages in a module unless the module is a bean archive and the alternative is explicitly selected in that bean archive.

换句话说,您必须在使用该 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,替代选择仅适用于在 beans.xml 中声明替代选择的模块,但事实并非如此对于 EJB。因此,您的 D 替代方案(即 @Stateless)对整个应用程序都有效。

关于java - 如何将带有 CDI 的 @Alternative 从 WAR 注入(inject)到 EJB 模块中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17401985/

相关文章:

java - 为基于 Java 文本的游戏制作控制台

Javafx 更改 osx 菜单栏名称

java - 未找到 ManagedExecutorService

jakarta-ee - org.codehaus.classworlds.NoSuchRealmException : plexus. 核心

java - 如何更改tomcat或jetty下的Java webapp 'WEB-INF path'约定

java - servlet 中的 EJB 注入(inject)失败

jpa - 如何在 JPA 中正确执行多对多连接表?

java - Jboss AS 6 - 如何通过 JNDI 查找 EJB

java - 如何向对象ArrayList添加多个值?

java - 为什么 DistributedCache 会破坏我的文件名