Почему производители не наследуются в 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 один из бобов?

С моей точки зрения это просто дизайнерское решение. Вероятно, на месте, чтобы предотвратить дальнейшую путаницу. Хотя я знаю, что это не тот ответ, так что вы, вероятно, ищете, допрос, так что старые конструкции редко приходят с более точными ответами:-)

Другие вопросы по тегам