1

给定

public class BeanContainer {
   @Produces
   Bean bean = new Bean();
}

及其替代方案:

@Alternative
public class BeanContainerAlt extends BeanContainer {
    @Produces
    int producerInt = 10;
}

比恩在哪里

public class Bean {
    boolean didPostConstruct = false;
    @PostConstruct
    public void postConstruct() {
        didPostConstruct = true;
    }
}

注入 MainClass:

public class MainClass {
    @Inject
    Bean bean;
    @Inject
    Integer producedInt;
}

然后:

  Weld weld = new Weld()
            .disableDiscovery()
            .addBeanClass(MainClass.class)
            .addBeanClass(BeanContainer.class)
            .addBeanClass(BeanContainerAlt.class)
            .alternatives(BeanContainerAlt.class);
    WeldContainer container = weld.initialize();
    final MainClass mainClass = container.select(MainClass.class).get();
    assertFalse(mainClass.bean.didPostConstruct);
    assertEquals(10, (long)mainClass.producedInt);
    BeanContainer containerObject = container.select(BeanContainer.class).get();
    assertEquals(BeanContainerAlt.class, containerObject.getClass());

没有错误。我原以为必须使用 addBeanClass 添加Bean.class才能满足MainClass中的注入。解释是BeanContainerAlt的超类,其Producers应该是无效的,产生了Bean-Object。这种行为是有意的还是根据规范(我没有找到),它可能在焊接文档中定义吗?

源代码可以在 examplesrc中找到

mvn clean install -Dtest=ReproProducersInSuperclasses 

在那个项目中应该让它运行

4

1 回答 1

0

实际上,带有注释的字段和方法@Producer不是继承的——正如在接受的答案中所讨论的,为什么生产者在 CDI 中没有被继承

但是,根据CDI 规范

5.1.2. 启用和禁用的 bean

如果满足以下条件,则称启用了 bean:

  • (E1) 它被部署在一个 bean 档案中,并且
  • (E2) 它不是禁用 bean 的生产者方法或字段,并且
  • (E3) 它没有被任何其他启用的 bean 特化,如 Specialization 中所定义,并且
  • (E4) 它不是替代品,或者它是至少一个 bean 存档或应用程序的选定替代品。

否则,该 bean 被称为禁用。

根据上面的这些定义和代码:

  • BeanContainer不是替代品(E4),因此启用了托管 bean
  • BeanContainerAlt一个选定的替代方案(E4),因此启用了托管 bean
  • Beanint启用是因为它们不是禁用 bean (E2) 的生产者方法或字段,因为BeanContainerBeanContainerAlt都被启用(E4)

BeanContainer因此,两者中的生产者字段BeanContainerAlt都用于解决依赖关系。


未部署BeanContainer时(E1)测试失败如下图:

WELD-001408: Unsatisfied dependencies for type Bean with qualifiers @Default
at injection point [BackedAnnotatedField] @Inject
net.oneandone.iocunit.testalt.MainClass.bean

未选中BeanContainerAlt时测试失败如下图(E4):

WELD-001408: Unsatisfied dependencies for type Integer with qualifiers @Default
at injection point [BackedAnnotatedField] @Inject
net.oneandone.iocunit.testalt.MainClass.producedInt
于 2019-04-04T00:20:05.943 回答