Это вопрос безопасного разрешения, и он работает как задумано. Из спецификации 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
.