Reputation: 3593
Given
public class BeanContainer {
@Produces
Bean bean = new Bean();
}
and its alternative:
@Alternative
public class BeanContainerAlt extends BeanContainer {
@Produces
int producerInt = 10;
}
where Bean is
public class Bean {
boolean didPostConstruct = false;
@PostConstruct
public void postConstruct() {
didPostConstruct = true;
}
}
injected into MainClass:
public class MainClass {
@Inject
Bean bean;
@Inject
Integer producedInt;
}
Then:
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());
gives no error. I would have expected that Bean.class would have to be added using addBeanClass to be able to satisfy the inject in MainClass. The explanation is that the Superclass of BeanContainerAlt whose Producers should imO not be effective, produces the Bean-Object. Is that behavior intended or even according to the spec (I did not find it), is it probably defined in the weld-documentation?
The sourcecode can be found in examplesrc
mvn clean install -Dtest=ReproProducersInSuperclasses
in that project should make it run
Upvotes: 1
Views: 126
Reputation: 1756
Indeed, the fields and methods annotated with @Producer
are not inherited - as discussed in the accepted answer to Why are Producers not inherited in CDI
However, according to the CDI specification:
5.1.2. Enabled and disabled beans
A bean is said to be enabled if:
- (E1) it is deployed in a bean archive, and
- (E2) it is not a producer method or field of a disabled bean, and
- (E3) it is not specialized by any other enabled bean, as defined in Specialization, and either
- (E4) it is not an alternative, or it is a selected alternative of at least one bean archive or the application.
Otherwise, the bean is said to be disabled.
According to these definitions and code above:
BeanContainer
is not an alternative (E4) and therefore is enabled managed beanBeanContainerAlt
is a selected alternative (E4) and therefore is enabled managed beanBean
and int
are enabled because they are not a producer method or field of a disabled bean (E2), as BeanContainer
and BeanContainerAlt
are both enabled (E4)Therefore producer fields in both BeanContainer
and BeanContainerAlt
are used to resolve dependencies.
The test fails as shown below when BeanContainer
is not deployed (E1):
WELD-001408: Unsatisfied dependencies for type Bean with qualifiers @Default
at injection point [BackedAnnotatedField] @Inject
net.oneandone.iocunit.testalt.MainClass.bean
The test fails as shown below when BeanContainerAlt
is not selected (E4):
WELD-001408: Unsatisfied dependencies for type Integer with qualifiers @Default
at injection point [BackedAnnotatedField] @Inject
net.oneandone.iocunit.testalt.MainClass.producedInt
Upvotes: 0