【问题标题】:Weld CDI: Producers in superclasses of alternatives are effective despite cdi-specWeld CDI:尽管有 cdi-spec,但超类替代品的生产者仍然有效
【发布时间】:2019-06-16 00:52:01
【问题描述】:

给定

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 

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

【问题讨论】:

    标签: cdi weld jboss-weld weld-se


    【解决方案1】:

    确实,使用 @Producer 注释的字段和方法不会被继承 - 正如对 Why are Producers not inherited in CDI 的已接受答案中所讨论的那样

    不过根据CDI specification

    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)

    因此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
    

    【讨论】:

    • 是否有机会获得对上述答案的反馈?
    猜你喜欢
    • 1970-01-01
    • 2017-08-04
    • 2023-03-29
    • 1970-01-01
    • 2015-04-08
    • 1970-01-01
    • 2022-10-12
    • 2016-02-14
    • 1970-01-01
    相关资源
    最近更新 更多