2016-11-17 9 views
0

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

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

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

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

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

ответ

0

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

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

Первый должен был наблюдать 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); 
} 

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

+0

Если я правильно понимаю, что вы предлагаете, это наложить вето на исходные бобы. Но это не проблема в моем случае, так как они не подходят для какой-либо точки инъекции и проверяются вручную только прокси-серверами при вызове метода. Проблема заключается в том, что есть две точки впрыска с одним и тем же типом и квалификаторами и два точно одинаковых прокси (только с разными настройками внутри них). – livthomas

+0

Хорошо, тогда я мог бы неправильно понять ваш текст. Возможны фрагменты кода. Я думал, что кандидаты на вступление - это 1) исходный боб, 2) ваш вновь созданный прокси. – Siliarus

+0

На самом деле, проект имеет открытый исходный код, поэтому вы можете видеть все это.Я внес изменения, описанные здесь в [this commit] (https://github.com/SilverThings/SilverWare/commit/abb44eae805f78f8b88959bd740f9d31cfe042d8). – livthomas