Weld CDI:尽管有cdi-spec,但超级类别的生产商仍然有效

问题描述 投票:1回答:1

特定

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

及其替代方案:

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

Bean在哪里

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的超类,其生产者应该无效,生成Bean-Object。这种行为是打算还是根据规范(我没有找到它),它是否可能在焊接文档中定义?

源代码可以在examplesrc中找到

mvn clean install -Dtest=ReproProducersInSuperclasses 

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

cdi weld jboss-weld weld-se
1个回答
0
投票

实际上,用@Producer注释的字段和方法不是遗传的 - 正如Why are Producers not inherited in CDI公认的答案中所讨论的那样

但是,根据CDI specification

5.1.2。启用和禁用Bean

如果出现以下情况,则说启用了bean:

  • (E1)它部署在一个bean存档中,并且
  • (E2)它不是禁用豆的生产者方法或领域,并且
  • (E3)它不是由Specialization中定义的任何其他启用的bean专用的
  • (E4)它不是替代品,或者它是至少一个bean存档或应用程序的选定替代品。

否则,该bean被认为是禁用的。

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

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

因此,BeanContainerBeanContainerAlt中的生成器字段用于解析依赖关系。


未部署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
© www.soinside.com 2019 - 2024. All rights reserved.