[Продолжая эту серию, мы будем ссылаться на некоторые материалы и примеры из спецификации CDI 2.x ].
Для того чтобы контейнер CDI распознал ваш компонент для инъекции, ваш компонент должен быть квалифицирован. Этого можно достичь, связав компонент с типом квалификатора. Тип квалификатора представляет некоторую видимую клиентом семантику, связанную с типом, который удовлетворяется некоторыми реализациями типа (а не другими). Другими словами, тип квалификатора идентифицирует компонент с типом, который может быть удовлетворен одной конкретной реализацией того же типа (иначе он становится неудовлетворенной зависимостью ).
Давайте посмотрим, как компонент может быть квалифицирован с помощью типов определителя компонента.
Типы определителей бобов
Существует 3 стандартных квалифицированных типа, которые определены в пакете javax.enterprise.inject
:
@Любой
: Каждый компонент имеет встроенный квалификатор@Any
, даже если он явно не объявляет этот квалификатор, за исключением специального@New
.@Default
: Если компонент явно не объявляет квалификатор, отличный от@Named
, компонент имеет квалификатор@По умолчанию
.@Новый
: Квалификатор@New
позволяет приложению получить новый экземпляр компонента, который не привязан к объявленной области видимости, но был выполнен ввод зависимостей.
Следующие заявления эквивалентны:
@Default public class Order { ... }
public class Order { ... }
Оба объявления приводят к созданию компонента с двумя квалификаторами: @Any
и @Default
.
Квалификатор по умолчанию также предполагается для любой точки внедрения, которая явно не объявляет квалификатор, таким образом, следующие объявления, в которых использование аннотации @Inject
идентифицирует параметр конструктора как точку внедрения, эквивалентны:
public class Order { @Inject public Order(@Default OrderProcessor processor) { ... } }
public class Order { @Inject public Order(OrderProcessor processor) { ... } }
В заключение, квалификатор @Any
и @Default
всегда предполагаются во время квалификации компонента, а также в точке внедрения, когда квалификатор не был явно объявлен.
Квалификатор @Named
@Named
определяется пакетом javax.inject
. Этот квалификатор используется для указания имени компонента. Например, этот компонент называется текущий заказ
:
@Named("currentOrder") public class Order { ... }
Приведенное выше объявление приводит к созданию компонента с тремя квалификаторами: @Any
, @Default
и @Named("currentOrder")
.
Если @Named
объявлен компонентом без указания имени компонента, используется имя компонента по умолчанию после преобразования первого символа имени класса в нижний регистр. Например, используя приведенный выше пример, если Order
класс был просто аннотирован с помощью @Named
, имя компонента по умолчанию будет order
.
Для получения дополнительной информации, пожалуйста, обратитесь к раздел 3.1.5 Имя компонента по умолчанию для управляемого компонента .
Если @Named
не объявлен ни компонентом, ни его прототипами, у компонента нет имени.
Теперь, когда у вас есть общее представление о квалификационных компонентах, давайте рассмотрим различные примеры квалификационных компонентов с использованием типов определителей компонентов. Обратите внимание, что мы установили bean-discovery-mode
как все
, контейнер CDI успешно распознал наши классы как квалифицированные классы, готовые к введению.
Пример 1: Внедрение CDI неявного класса @Default bean (без интерфейсов)
Исходный код учебника можно найти здесь , а исполняемый файл класса можно найти здесь и это следует примеру, упомянутому в предыдущей статье. Служба По умолчанию
и
Пример 2: Внедрение CDI неявного класса @Default bean (внедрение в интерфейс)
Это расширение примера 1, но в данном случае Служба по умолчанию
реализует интерфейс Service
. Исходный код учебника можно найти здесь , а исполняемый файл класса можно найти здесь . Вкл. Главный контроллер
класс мы просто вводим в свойство, которое ссылается на интерфейс Service
. Видя, что на нет аннотаций Служба по умолчанию
, контейнеру CDI удалось успешно обнаружить одну реализацию службы интерфейс и, таким образом, создание контекстуального контекста вокруг интерфейса
Service
(который, в свою очередь, будет вводить Служба по умолчанию
при необходимости). Служба по умолчанию
неявно квалифицируется как @Any
и @Default
.
Давайте сделаем здесь паузу. В следующем уроке мы рассмотрим, как решать инъекции классов/интерфейсов, которые могут создавать более 1 инъекции зависимостей, используя @Alternative
а также определение нашего собственного пользовательского типа квалификатора.
Оригинал: “https://dev.to/theelitegentleman/understanding-jakarta-ee-8-c-d-i-part-2-qualifying-your-beans-2mi2”