焊接CDI:尽管有CDI规范,但超类替代产品中的生产商仍然有效

时间:2019-01-22 14:13:42

标签: cdi weld jboss-weld weld-se

给出

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 
该项目中的

应该使其运行

1 个答案:

答案 0 :(得分:0)

实际上,没有用@Producer注释的字段和方法-如在对Why are Producers not inherited in CDI的公认答案中所讨论的

但是,根据CDI specification

  

5.1.2。启用和禁用的豆子

     

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

     
      
  • (E1)将其部署在Bean归档文件中,并且
  •   
  • (E2)它不是禁用bean的生产者方法或字段,并且
  •   
  • (E3),它不是由任何其他启用的bean专门化的,如“专门化”中所定义的那样,
  •   
  • (E4)它不是替代方案,或者是至少一个bean归档文件或应用程序的选定替代方案。
  •   
     

否则,据说该bean被禁用了。

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

  • BeanContainer不可替代的(E4),因此是启用的托管bean
  • BeanContainerAlt选定的替代方案(E4),因此是启用的托管bean
  • Beanint已启用 ,因为它们不是禁用豆的生产者方法或字段(E2),例如{{ 1}}和BeanContainer均已启用 (E4)

因此,BeanContainerAltBeanContainer中的生产者字段用于解析依赖关系。


当未BeanContainerAlt未部署(E1)时,测试失败,如下所示:

BeanContainer

当未选择WELD-001408: Unsatisfied dependencies for type Bean with qualifiers @Default at injection point [BackedAnnotatedField] @Inject net.oneandone.iocunit.testalt.MainClass.bean (E4)(E4)时,测试失败,如下所示:

BeanContainerAlt