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