1

我有projectAprojectBprojectCEclipse Maven 项目。

  • ProjectA包含:
    • IMyApi界面。
    • “空”META-INF\beans.xml文件。
  • ProjectB包含:
    • IMyConfig界面。
    • MyConfigJndi的实施IMyConfig
    • MyApiImpl执行IMyApi,带有一个属性@Inject private IMyConfig config;
    • “空”META-INF\beans.xml文件。
  • ProjectC包含:
    • MyConfigAlter实现IMyConfig,标记为@Alternative
    • 初始化 Weld SE 并检索bean的Main类(和方法) 。IMyApi
    • a部分META-INF\beans.xmlMyConfigAlter列出的位置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();
4

2 回答 2

4

alternatives使用描述符中的元素选择替代方案beans.xml只会影响相应的 bean 存档,即ProjectC在您的情况下,如Declaring selected alternatives for a bean archive 中所述。基于此,ProjectBbean 存档MyConfigJndi注入实现是合乎逻辑的。

从 CDI 1.2 开始,可以使用为应用程序声明选定替代方案中@Priority记录的注释为应用程序全局选择替代方案。

所以在你的情况下,你可以写:

@Priority(Interceptor.Priority.Application)
@Alternative
class MyConfigAlter {
}
于 2015-12-01T17:42:24.527 回答
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 规范,因此没有定义类路径如何在此模式下运行。这不一定是 SE 应用程序的设计方式,因为每个 JAR 都没有唯一的类加载器。

于 2015-12-02T12:28:06.250 回答