Когда происходит инъекция CDI? - PullRequest
1 голос
/ 04 июня 2019

Я работаю с сервером Wildfly и мне интересно, когда на самом деле происходит инъекция.Это в то время, когда это необходимо, или есть какой-то механизм для разрешения зависимостей раньше?

Если я использую аннотацию @Inject, я знаю, что получу ошибку, если что-то не удастся внедрить (двусмысленность и т. Д.)).Означает ли это, что инъекция выполняется во время развертывания?Если так, как это относится к этому сценарию: предположим, у меня есть BeanOne, который вводит BeanTwo, и BeanTwo вводит BeanThree.Означает ли это, что эта цепочка bean-компонентов будет распределена во время развертывания?Что произойдет, если у меня будет больше цепочек, чем эта, и предположим, что мой пул бинов ограничен каким-то небольшим числом, скажем, 2?Как это можно сделать во время развертывания, когда не хватает бинов и некоторым из них придется ждать своих зависимостей?

Отличается ли этот случай от программного поиска bean-компонентов: CDI.current().select(MyStatelessBean.class).get();

или даже внедрения с использованием экземпляров: @Inject Instance<MyStatelessBean> bean;?

1 Ответ

2 голосов
/ 05 июня 2019

Ошибки, которые вы получаете, обычно происходят из так называемой фазы проверки.Это делается во время развертывания и не означает, что фактические компоненты будут созданы.

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

На практике это означает, что когда вы @Inject Foo foo;, все, что вы получаете, на самом деле является проксиобъект.«Оболочка» без состояния, которая знает, как получить так называемый контекстный экземпляр при необходимости .Контекстный экземпляр создается лениво, по требованию, когда вы впервые пытаетесь использовать этот компонент, как правило, когда вы впервые пытаетесь вызвать метод для него.

Благодаря статической природе CDI, во время развертывания всеЗависимости ваших bean-компонентов известны и могут быть проверены, поэтому вы можете проверить цепочку, которая была в вашем вопросе, и вы узнаете, все ли bean-компоненты доступны / неудовлетворены / неоднозначны.

Что касается динамического разрешения, например, Instance<Bar>, это несколько другое.CDI может проверять только первоначальное объявление, которое у вас есть;в моем примере выше, это bean-компонент типа Foo с квалификатором по умолчанию.Любые последующие вызовы методов .select() выполняются во время выполнения, поэтому вам всегда нужно проверять, доступен ли экземпляр, который вы только что пытались выбрать, потому что вы можете легко выбрать либо тип, не являющийся компонентом, либо тип компонента, но с недопустимым квалификатором (с).Instance API предлагает специальные методы для этого.

...