给出
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
该项目中的应该使其运行
答案 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 Bean
和int
已启用 ,因为它们不是禁用豆的生产者方法或字段(E2),例如{{ 1}}和BeanContainer
均已启用 (E4)因此,BeanContainerAlt
和BeanContainer
中的生产者字段用于解析依赖关系。
当未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