Конфигурация зависимости синтетического компонента в CDI / Weld - PullRequest
0 голосов
/ 12 февраля 2019

У меня есть интересная проблема, касающаяся конфигурации синтетических компонентов CDI, которая на самом деле может быть достойна обновления спецификации.

Многие люди комментируют здесь и в других местах определенное отсутствие CDI в отношении конфигурации во время выполнения.В частности, такие вещи, как Entity Managers, которые имеют ограниченное количество фактических значений, но которые создают точку внедрения для каждого из них, или используют исключительно бины @Dependent scope, нереалистичны.В случае Entity Manager это делает отслеживание областей транзакций трудным или невозможным, но есть много похожих случаев, которые можно себе представить.

По сути, я хочу иметь возможность что-то вроде этого:

InjectionPoint:

@Inject
@SomeQualifier("differentiating value")
ExternalResourceObject resourceObject;

InjectionTarget:

@Produces
@ApplicationScoped
@SomeQualifier("")
public ExternalResourceObject produceResource(SomeQualifier qualifierValue) {
  // Use qualifierValue to produce an instance unique to this particular value
}

На практике происходит то, что для доступа к SomeQualifier необходимо использовать InjectionPoint, что затем заставляет всего производителя требовать @Dependent scoping.Кроме того, в параметре должен быть определен @Nonbinding для параметра, иначе производитель не будет соответствовать разным конфигурациям, которые могут быть созданы.

Чтобы избежать этого, я прибег к плагину CDI, который получает ProcessInjectionPoint иСобытия ProcessType, затем в AfterBeanDiscovery, они совпадают с двумя, создавая синтетические компоненты и вставляя аннотированное поле @Configuration.Затем происходит нормальная инициализация bean-компонента в @PostConstruct, который выбирает поле @Configuration, если оно присутствует, создавая соответствующий тип bean-компонента конфигурации, соответствующим образом аннотированный, который затем внедряет контейнер, где это необходимо.

Это работает на самом деле довольно хорошо.С небольшой осторожностью декораторы и перехватчики даже применяются корректно, хотя я не видел много примеров, где это происходит в дикой природе.

Вот суть проблемы:

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

В настоящее время я использую специально названныйстатический метод для каждого класса, который передает параметр @Configuration, чтобы спросить его, какие зависимые точки внедрения ему понадобятся, а затем рекурсивно связать их с каждой последующей обнаруженной точкой внедрения.Этот метод специфичен для моего плагина и поэтому не входит в спецификацию CDI.(хотя технически весь этот механизм в некотором роде)

Вопрос: Есть ли лучший (менее хакерский) способ решения проблемы этих синтетических конфигураций InjectionPoints?В частности, если бы был способ перехватить события типа Bean Not Found и ответить соответствующим образом настроенным bean-компонентом для этого конкретного случая (если, конечно, присутствует свойство @Configuration), это устранит необходимость в этом методе статического обнаружения, ноЯ не могу найти ничего подобного в спецификации.

Light rant: Это похоже на очень распространенный вариант использования, особенно для таких вещей, как EntityManager, и даже в этом случае можно представитьпулы соединений, являющиеся их собственным зависимым ресурсом CDI, который не был бы известен при обнаружении точки внедрения.

Кажется, что действительно вполне разумный способ обойти это просто разрешить внедрение необходимой конфигурации в InjectionTarget, обозначенныйс помощью такого классификатора, как @ Configuration.

Наличие механизма, подобного этому, in-spec будет иметь большое значение для сокращения некоторого стандартного кода повторяющейся точки впрыска вокруг контекстов постоянства и других объединенных ресурсов, многие из которых не являютсяNопределяется правильно при загрузке контейнера.

...