Почему производители не наследуются в CDI
Учитывая следующие занятия
private static class ProducedInSubClass {
}
private static class ProducedInSuperClass {
}
public static class SuperClass {
@Produces
public ProducedInSuperClass producedInSuperClass = new ProducedInSuperClass();
}
public static class SubClass extends SuperClass {
@Produces
ProducedInSubClass producedInSubClass = new ProducedInSubClass();
}
public static class BeanWithSubClass {
@Inject
SubClass subClass;
@Inject
ProducedInSuperClass producedInSuperClass;
@Inject
ProducedInSubClass producedInSubClass;
}
Внедрение ProducedInSuperClass остается неудовлетворенным. Это соответствует CDI-Spec Глава 4.2, я знаю.
Чтобы это работало, мне нужно расширить SubClass на
@Produces
ProducedInSuperClass producedInSuperClassInSubClass = producedInSuperClass;
Кто-нибудь может дать объяснение этому? Почему Инъекции, Перехватчики Аннотаций... унаследованы, но не Производители?
2 ответа
Почему... унаследованы, но не продюсеры?
Выдержка из JavaDoc @Produces:
Методы и поля источника не наследуются подклассами бина.
Если бы методы и поля производителя были унаследованы, тогда существовало бы несколько бинов... подходящих для внедрения в точку внедрения, которую CDI рассматривает как неоднозначную зависимость.
С другой стороны, CDI поддерживает специализацию метода производителя:
@Mock
public class MockShop extends Shop {
@Override @Specializes
@Produces
PaymentProcessor getPaymentProcessor() {
return new MockPaymentProcessor();
}
@Override @Specializes
@Produces
List<Product> getProducts() {
return PRODUCTS;
}
...
}
Есть ли причина, по которой вы работаете только со статическими классами? Продюсер должен быть помещен в фактический компонент CDI, чтобы быть распознанным. Ваш образец вырван из контекста, поэтому я не могу сказать, будут ли они фактически распознаны как бобы.
Однако, перенеся ваш образец в нестатический тестовый пример (с некоторыми компонентами @Vetoed и производителями для них), он будет работать так, как вы ожидаете - оба производителя будут найдены и будут производить вводимые компоненты. Так что, возможно, вам нужно поделиться полным воспроизводимым образцом, и мы можем перейти оттуда.
Я подозреваю, что наследство, о котором вы спрашиваете, не является настоящей проблемой здесь. Во всяком случае, он разработан так, как начиная с CDI 1.0, поэтому найти обсуждение по этому вопросу в лучшем случае было бы проблематично (по крайней мере, без проблем JIRA, я проверил там). Но одна причина, приходящая на ум, сразу - предположить, что наследство было на месте для производителей. Тогда ваш сценарий выше будет иметь производителя для ProducedInSuperClass
в SuperClass
но из-за наследования также в SubClass
, Предполагая, что оба являются допустимыми для внедрения (ни один не отключен посредством специализации), вы столкнулись с неоднозначным исключением зависимости, поскольку у вас есть два производителя для одного и того же типа компонента с одинаковыми квалификаторами компонента, потому что SuperClass
а также SubClass
две разные бобы, и оба содержат производителя. Я бы сказал, что это справедливая причина отключения наследства для производителей. Кроме того, все еще с включенным наследованием, вы можете переопределить метод в подклассе, и возникнут дополнительные вопросы - вы сохраняете оба или отключаете оригинальный? Если вы сохраните их, каковы будут ограничения на новый метод? Что делать, если вы решите либо @Vetoed
один из бобов?
С моей точки зрения это просто дизайнерское решение. Вероятно, на месте, чтобы предотвратить дальнейшую путаницу. Хотя я знаю, что это не тот ответ, так что вы, вероятно, ищете, допрос, так что старые конструкции редко приходят с более точными ответами:-)