Разрешение неоднозначных зависимостей с расширением CDI

Я пытаюсь изменить наше существующее расширение CDI, которое создает свои собственные прокси-компоненты. Теперь для каждой службы создается только один прокси. Службы имеют что-то вроде области приложения, поэтому всегда существует только один экземпляр службы.

Чего я хочу добиться, так это создать один прокси-компонент для каждой точки внедрения. Мне они нужны, чтобы хранить некоторую информацию, специфичную для данной точки впрыска. Если для одной и той же службы имеется больше точек внедрения, будет больше прокси-компонентов, но за ними будет стоять один экземпляр службы. Однако, когда я изменяю поведение таким образом, Weld жалуется на неоднозначные зависимости, поскольку не может выбирать между двумя абсолютно одинаковыми прокси.

Как я могу это исправить? По сути, я наблюдаю за событием ProcessBean и создаю новый прокси для каждой точки внедрения каждого отдельного обнаруженного компонента. Затем я добавляю все эти прокси-бины в контейнер, используя метод AfterBeanDiscovery#addBean. Мне как-то нужно было бы пропустить этот последний шаг и ввести их вручную в их точки инъекции или иметь возможность влиять на решение о выборе правильного компонента для инъекции. Если мне дадут точку внедрения и список неоднозначных зависимостей, которые можно в нее внедрить, я смогу выбрать правильную на основе ее атрибута. Но я действительно не знаю, возможно ли принять это решение для Weld и как я могу это сделать.

EDIT: я просто хочу реализовать свою собственную область видимости, аналогичную @Dependent, но с прокси-серверами, в которых я могу хранить некоторую дополнительную информацию, связанную с данной точкой внедрения.

EDIT2: я, наконец, исправил это, создав новый квалификатор, содержащий информацию о конкретной точке инъекции. Этот квалификатор добавляется как к точке внедрения, так и к ее прокси. Но это не очень хорошее решение, так как мне приходится заменять точки внедрения собственной реализацией, которая позволяет модифицировать коллекцию квалификаторов. Я чувствую, что должно быть более элегантное решение. Пожалуйста, дайте мне знать, если вы можете что-нибудь придумать.


person livthomas    schedule 17.11.2016    source источник


Ответы (1)


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

Если я правильно понял ваш случай, вы можете использовать двух наблюдателей в одном расширении.

Сначала можно было бы наблюдать фазу ProcessBeanAttributes и veto() исходный компонент, который вам не нужен.

void observePBA(@Observes ProcessBeanAttributes<?> bean) {
  // I used '?' as a type, so here you do your check for 
  // the actual bean class to know which one is it and whether
  // you actually want to veto such bean
  bean.veto();
}

Другой наблюдатель — это то, что у вас уже есть — добавление собственного компонента в AfterBeanDiscovery#addBean.

void observeABD(@Observes AfterBeanDiscovery abd) {
  // add your custom bean, assuming you have it prepared somewhere
  abd.addBean(myCustomBean);
}

Таким образом, когда контейнер загрузится, вы удалите исходные компоненты и добавите свой собственный. Таким образом, у Weld не должно быть неоднозначных проблем с разрешением.

person Siliarus    schedule 21.11.2016
comment
Если я правильно понимаю, вы предлагаете наложить вето на оригинальные бобы. Но в моем случае это не проблема, поскольку они не подходят ни к одной точке внедрения и прокси-серверы просматривают их вручную только при вызове метода. Проблема в том, что есть две точки инжекции с одинаковым типом и квалификаторами и создаются два абсолютно одинаковых прокси (только с разными настройками внутри них). - person livthomas; 22.11.2016
comment
Тогда я мог неправильно понять ваш текст. Фрагменты кода могут помочь. Я думал, что кандидатами на инъекцию являются 1) оригинальный bean-компонент, 2) ваш только что созданный прокси. - person Siliarus; 23.11.2016
comment
На самом деле, проект с открытым исходным кодом, поэтому вы можете увидеть все это. Я внес изменения, описанные здесь, в этой фиксации. - person livthomas; 23.11.2016