[英]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.