В этом руководстве мы покажем вам, как добиться внедрения зависимостей в управляемых компонентах CDI. В частности, мы будем использовать аннотацию @Inject
предоставляемую API-интерфейсом CDI, чтобы внедрить компонент CDI в другой компонент. Таким образом, компонент может использоваться в приложении, таком как приложение JavaServer Faces.
CDI предоставляет несколько способов внедрить bean-компонент в приложение. Мы можем внедрить bean-компонент CDI, используя Инъекцию Зависимости Поля, Инъекцию Зависимости Конструктора или Инъекцию Зависимости через метод установки. Мы также можем вводить аргументы методов-производителей, но это выходит за рамки данного руководства. Давайте рассмотрим все способы введения, предоставляемые CDI:
1. Инъекция зависимости от поля
Самый простой способ внедрить bean-компонент CDI — добавить аннотацию @Inject
в свойство для @Inject
. Давайте посмотрим на пример ниже. GreetingBean
имеет аннотированное поле @Inject
, которое является helloBean
. Таким образом, другой компонент, HelloBean
, внедряется в GreetingBean
.
01
02
03
04
05
06
07
08
09
10
|
package com.javacodegeeks.snippets.enterprise.cdibeans; import javax.inject.Inject; public class GreetingBean { @Inject private HelloBean helloBean; } |
2. Внедрение зависимостей в конструктор
Когда компонент CDI инициализируется, контейнер будет использовать конструктор по умолчанию. Когда есть другой конструктор, аннотированный аннотацией @Inject
, контейнер будет автоматически использовать этот конструктор, и таким образом аргумент, переданный в конструкторе, будет введен в bean-компонент. Здесь следует отметить, что у нас может быть только одна точка инжекции конструктора. Если мы создадим еще @Inject
аннотированный конструктор @Inject
, поведение контейнера будет непредсказуемым.
В приведенном ниже фрагменте кода GreetingBean
имеет конструктор, аннотированный аннотацией @Inject
и аргументом, то есть другим компонентом HelloBean
. Таким образом, инъекция достигается.
01
02
03
04
05
06
07
08
09
10
11
12
13
14
|
package com.javacodegeeks.snippets.enterprise.cdibeans; import javax.inject.Inject; public class GreetingBean { private final HelloBean helloBean; @Inject public GreetingBean(HelloBean helloBean){ this .helloBean = helloBean; } } |
3. Внедрение зависимостей через метод установки
В приведенном ниже примере метод setHelloBean(HelloBean helloBean)
аннотируется аннотацией @Inject
. Таким образом, когда GreetingBean
инициализируется контейнером, метод будет вызван, так как он аннотирован HelloBean
будет HelloBean
.
01
02
03
04
05
06
07
08
09
10
11
12
13
|
package com.javacodegeeks.snippets.enterprise.cdibeans; import javax.inject.Inject; public class GreetingBean { private HelloBean helloBean; @Inject public void setHelloBean(HelloBean helloBean) { this .helloBean = helloBean; } } |
4. Использование классификатора @Any
@Any
можно использовать, когда у нас есть несколько реализаций одного интерфейса, и мы хотим внедрить их все в другой bean-компонент. Используя эту аннотацию, контейнер внедрит все реализации указанного интерфейса. Он используется с интерфейсом javax.enterprise.inject.Instance
предоставляемым API CDI, как показано в фрагменте кода ниже:
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
|
package com.javacodegeeks.snippets.enterprise.cdibeans; import javax.enterprise.inject.Any; import javax.enterprise.inject.Instance; import javax.inject.Inject; public class GreetingBean { @Inject public void getAllBeanImplementations( @Any Instance<HelloBean> beans) { for (HelloBean helloBean : beans) { System.out.println(helloBean.getClass().getCanonicalName()); } } } |
Здесь мы должны заметить, что если существует несколько зависимостей, которые удовлетворяют точке внедрения, и мы не будем использовать квалификатор @Any
, а попытаемся внедрить одну вместо @Any
, тогда контейнер не будет выполнен.
5. Использование прокси для реализации инъекции
Чтобы внедрить управляемый компонент в другой компонент (кроме аннотированных компонентов @Dependent
), контейнер CDI не будет передавать ссылку на сам внедренный компонент, а вместо этого будет передавать ссылку на прокси. Прокси-сервер обрабатывает все вызовы внедренного компонента прозрачно. Например, когда мы SessionScoped
компонент SessionScoped
компонент ApplicationScoped
и многие клиенты обращаются к ApplicationScopedBean
, прокси-серверы используются для обработки вызовов к внедренным компонентам. Каждый прокси может перенаправить вызов на правильный бин.
Наконец, обратите внимание, что прокси-сервер CDI создается путем расширения класса компонента и переопределения всех методов, не являющихся pivate. Примитивные типы не могут быть введены. Класс bean-компонента должен иметь не приватный конструктор по умолчанию и не должен быть финальным или иметь финальные методы.
Это было руководство по @Inject
зависимостей в управляемых компонентах CDI с использованием аннотации @Inject
.