在Java SE上焊接不使用替代方案

时间:2015-12-01 11:53:49

标签: java cdi weld weld-se

我有projectAprojectBprojectC 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
    • 初始化Weld SE并检索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();

2 个答案:

答案 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应用程序的设计方式。