Weld CDI: производители суперклассов альтернатив эффективны, несмотря на cdi-spec
Дано
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());
не дает ошибок. Я ожидал, что Bean.class должен быть добавлен с использованием addBeanClass, чтобы можно было выполнить инъекцию в MainClass. Объяснение состоит в том, что Суперкласс BeanContainerAlt, чьи Производители должны быть неэффективными, создает Боб-объект. Предназначено ли это поведение или даже в соответствии со спецификацией (я не нашел его), возможно, оно определено в документации по сварке?
Исходный код можно найти в examplesrc
mvn clean install -Dtest=ReproProducersInSuperclasses
в этом проекте должен заставить его работать
0 ответов
Действительно, поля и методы помечены @Producer
не наследуются - как обсуждалось в принятом ответе на вопрос, почему производители не наследуются в CDI
Однако согласно спецификации CDI:
5.1.2. Включенные и отключенные бины
Бин считается включенным, если:
- (E1) он развернут в архиве компонентов и
- (E2) это не метод производителя или поле отключенного компонента, и
- (E3) он не специализирован никаким другим включенным компонентом, как определено в Специализации, и либо
- (E4) это не альтернатива, или это выбранная альтернатива, по крайней мере, одного архива бина или приложения.
В противном случае бин считается отключенным.
В соответствии с этими определениями и кодом выше:
BeanContainer
не является альтернативой (E4) и, следовательно, включен управляемый компонентBeanContainerAlt
является выбранной альтернативой (E4) и, следовательно, включен управляемый компонентBean
а также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