我有projectA
,projectB
和projectC
Eclipse Maven项目。
ProjectA
包含:
IMyApi
interface。META-INF\beans.xml
档案。ProjectB
包含:
IMyConfig
interface。MyConfigJndi
IMyConfig
。MyApiImpl
实施IMyApi
,其中包含属性@Inject private IMyConfig config;
。META-INF\beans.xml
档案。ProjectC
包含:
MyConfigAlter
IMyConfig
的{{1}}实施,标记为@Alternative
。Main
bean的IMyApi
类(和方法)。META-INF\beans.xml
其中MyConfigAlter
部分列出了alternatives
。现在,我运行Main
类,并成功检索IMyApi
bean(作为MyApiImpl
实例)。但是这样的实例在其config
属性中注入了MyConfigJndi
实例,而不是替代版本(MyConfigAlter
)
我正在使用Eclipse Luna + M2Eclipse。
我做错了什么?
更新:我发现使用@Specializes
代替@Alternative
可以解决问题,但我仍然认为这不是正确的解决方案(在某些情况下我可能无法访问“默认”实现)。
更新2:
我正在使用Weld-se,2.2.10.Final:
<dependency>
<groupId>org.jboss.weld.se</groupId>
<artifactId>weld-se</artifactId>
<version>2.2.10.Final</version>
<scope>runtime</scope>
</dependency>
初始化只是
WeldContainer weld =
new Weld().
initialize();
IMyApi myApi =
weld.
instance().
select(
IMyApi.
class).
get();
答案 0 :(得分:4)
使用alternatives
描述符中的beans.xml
元素选择替代方案只会影响相应的bean存档,即ProjectC
,如Declaring selected alternatives for a bean archive中所述。基于此,ProjectB
bean存档注入了MyConfigJndi
实现是合乎逻辑的。
自CDI 1.2起,可以使用Declaring selected alternatives for an application中记录的@Priority
注释为应用程序全局选择替代方案。
所以在你的情况下,你可以写:
@Priority(Interceptor.Priority.Application)
@Alternative
class MyConfigAlter {
}
答案 1 :(得分:0)
解决此问题的另一种方法是使用-Dorg.jboss.weld.se.archive.isolation=false
- 来自http://docs.jboss.org/weld/reference/2.2.11.Final/en-US/html/environments.html#_bean_archive_isolation_2
发生这种情况的原因是类路径上的每个JAR都成为它自己的bean归档文件。由于1.2版的CDI规范不包括SE规范,因此没有定义类路径如何在此模式下运行。由于您没有为每个JAR提供独特的类加载器,因此这不一定是SE应用程序的设计方式。