特定
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
在那个项目中应该让它运行
实际上,用@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),因此启用了托管beanBeanContainerAlt
是一个选定的替代品(E4),因此启用了托管beanBean
和int
已启用,因为它们不是生产者方法或禁用豆类(E2)的字段,因为BeanContainer
和BeanContainerAlt
都已启用(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