Читаем Изучаем Java EE 7 полностью

Однако существует правило, что вы можете иметь только одну точку внедрения конструктора. Именно контейнер (а не вы) выполняет внедрение, так как вы не можете вызвать конструктор в управляемой среде. Поэтому для того, чтобы контейнер мог выполнить свою работу и внедрить правильные ссылки, разрешается только один конструктор компонентов.

Другой вариант — использовать внедрение сеттера, что выглядит как внедрение конструктора. Вам просто нужно добавить к сеттеру аннотацию @Inject:

@Inject

public void setNumberGenerator(NumberGenerator numberGenerator) {

··this.numberGenerator = numberGenerator;

}

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


Внедрение по умолчанию

Предположим, NumberGenerator имеет только одну реализацию (IsbnGenearator). Тогда CDI сможет внедрить его, просто самостоятельно используя аннотацию @Inject:

@Inject

private NumberGenerator numberGenerator;

Это называется внедрением по умолчанию. Каждый раз, когда компонент или точка внедрения не объявляет очевидным образом квалификатор, контейнер по умолчанию использует квалификатор @javax.enterprise.inject.Default. На самом деле предыдущему отрывку кода идентичен следующий:

@Inject @Default

private NumberGenerator numberGenerator;

@Default — это встроенный квалификатор, сообщающий CDI, когда нужно внедрить реализацию компонента по умолчанию. Если вы определите компонент без квалификатора, ему автоматически присвоится квалификатор @Default. Таким образом, код в листинге 2.6 идентичен коду в листинге 2.5.


Листинг 2.6. Компонент IsbnGenerator с квалификатором @Default

@Default

public class IsbnGenerator implements NumberGenerator {

··public String generateNumber() {

····return "13-84356-" + Math.abs(new Random(). nextInt());

··}

}

Если у вас есть только одна реализация компонента для внедрения, применяется поведение по умолчанию, а реализация будет внедрена непосредственно с использованием @Inject. Схема класса на рис. 2.4 показывает реализацию @Default (IsbnGenerator), а также точку внедрения по умолчанию (@Inject @Default). Но иногда приходится выбирать между несколькими реализациями. Это как раз тот случай, когда нужно использовать квалификаторы.


Рис. 2.4. Схема класса с квалификатором @Default


Квалификаторы

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

Итак, как же компонент выбирает, какая реализация (IsbnGenrator или IssnGenerator) будет внедряться? При объявлении и внедрении компонентов в большинстве фреймворков активно задействуется XML-код. CDI использует квалификаторы: в основном это аннотации Java, осуществляющие типобезопасное внедрение и однозначно определяющие тип без необходимости отката к строковым именам.

Предположим, у нас есть приложение с сервисом BookService, который создает книги с тринадцатизначным номером ISBN, и с LegacyBookService, создающим книги с восьмизначным номером ISSN. Как вы можете видеть на рис. 2.5, оба сервиса внедряют ссылку на один интерфейс NumberGenerator. Сервисы различаются реализациями благодаря использованию квалификаторов.


Рис. 2.5. Сервисы, использующие квалификаторы для однозначного внедрения


Квалификатор представляет определенную семантику, ассоциированную с типом и удовлетворяющую отдельной реализации этого типа. Это аннотация, которая определяется пользователем и, в свою очередь, сопровождается аннотацией @javax.inject.Qualifer. Например, мы можем использовать квалификаторы для замещения тринадцати- и восьмизначных генераторов чисел. Оба примера показаны в листингах 2.7 и 2.8.


Листинг 2.7. Тринадцатизначный квалификатор

@Qualifier

@Retention(RUNTIME)

Перейти на страницу:

Похожие книги

C# 4.0: полное руководство
C# 4.0: полное руководство

В этом полном руководстве по C# 4.0 - языку программирования, разработанному специально для среды .NET, - детально рассмотрены все основные средства языка: типы данных, операторы, управляющие операторы, классы, интерфейсы, методы, делегаты, индексаторы, события, указатели, обобщения, коллекции, основные библиотеки классов, средства многопоточного программирования и директивы препроцессора. Подробно описаны новые возможности C#, в том числе PLINQ, библиотека TPL, динамический тип данных, а также именованные и необязательные аргументы. Это справочное пособие снабжено массой полезных советов авторитетного автора и сотнями примеров программ с комментариями, благодаря которым они становятся понятными любому читателю независимо от уровня его подготовки. Книга рассчитана на широкий круг читателей, интересующихся программированием на C#.Введите сюда краткую аннотацию

Герберт Шилдт

Программирование, программы, базы данных
97 этюдов для архитекторов программных систем
97 этюдов для архитекторов программных систем

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

Билл де Ора , Майкл Хайгард , Нил Форд

Программирование, программы, базы данных / Базы данных / Программирование / Книги по IT