Как я могу обработать несколько методов удаления для унаследованных типов? - PullRequest
0 голосов
/ 30 октября 2019

У меня есть два класса.

class A {
}

class B extends A {
}

И в классе моего продюсера я объявил вот так.

@Produces A produceA(InjectionPoint ip) {
    return new A();
}

void disposeA(@Disposes A a) {
    // empty
}

@Produces B produceB(InjectionPoint ip) {
    return new B();
}

void disposeB(@Disposes B b) {
    // empty
}

И Weld жалуется.

....DefinitionException: WELD-000077: Cannot declare multiple disposal methods for this producer method.

Producer method:  org.jboss.weld.bootstrap.BeanDeployer@41e68d87
Disposal methods:  
  - Disposer method [[BackedAnnotatedMethod] ....Producer.disposeA(@Disposes A)],
  - Disposer method [[BackedAnnotatedMethod] ....Producer.disposeB(@Disposes B)]

Естьэто нормально? Как я могу решить это?

1 Ответ

3 голосов
/ 30 октября 2019

Это вопрос безопасного разрешения, и он работает как задумано. Из спецификации 3.4.3. Разрешение метода Disposer :

Метод Disposer привязан к методу производителя или полю производителя, если:

  • метод производителя или производительполе объявляется тем же классом компонента, что и метод disposer, и
  • поле метода-производителя или источника-производителя присваивается параметру disposed в соответствии с правилами безопасного разрешения типов, определенных в типографском разрешении(с использованием Assignability необработанных и параметризованных типов).

В вашем конкретном случае у вас есть метод продюсера produceB, который создает бин, типы которого будут {B, A, Object}. Типы являются производными от возвращаемого типа и будут содержать сам тип, все суперклассы и все реализованные интерфейсы (, как указано здесь в спецификации CDI ).

Затем у вас есть два метода disposer,один с параметром disposer A, другой с B. Вы можете думать об этих параметрах как о точках внедрения, если это помогает - ваш метод производителя produceB создает компонент, который подходит обоим этим утилизаторам, создавая, таким образом, двусмысленность, поскольку для Weld требуется не более одного метода утилизации для каждого компонента.

ЕслиВы хотите узнать больше о том, как именно работает безопасное разрешение, смотрите здесь .

Что касается того, как «разрешить» эту ситуацию, я могу подумать о двух подходах из головы (вероятно, есть и другие способы сделать это):

  • Вы можете объявить каждого производителя + диспозитора в другом компоненте. Согласно спецификации, disposer должен быть объявлен в том же компоненте, где находится производитель, так что это устранит эту проблему.
  • Вы можете использовать @Typed для производителя и ограничить типыproduceB только B.class, что также должно разрешить эту ситуацию, но боб больше не будет иметь права на инъекцию в любую точку инъекции с типом A.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...