Изучаем Java EE 7 - [22]

Шрифт
Интервал

InjectionPoint API. В листинге 2.16 атрибуты и возвращаемое значение, полученное посредством @Produces, не требуют никакой информации о том, куда они внедряются. Но в определенных случаях объектам нужна информация о точке их внедрения. Это может быть способ конфигурации или изменения поведения в зависимости от точки внедрения.

Например, рассмотрим создание автоматического журнала. В JDK для создания java.util.logging.Logger вам необходимо задать категорию класса, владеющего им. Скажем, если вам нужен автоматический журнал для BookService, следует написать:

>Logger log = Logger.getLogger(BookService.class.getName());

Как бы вы получили Logger, которому необходимо знать имя класса точки внедрения? В CDI есть InjectionPoint API, обеспечивающий доступ к метаданным, которые касаются точки внедрения (табл. 2.2). Таким образом, вам необходимо создать метод производителя данных, который использует InjectionPoint API для конфигурации правильного автоматического журнала. В листинге 2.18 показано, как метод createLogger получает имя класса точки внедрения.


Таблица 2.2. InjectionPoint API
МетодОписание
Type getType()Получает требуемый тип точки внедрения
Set getQualifiers()Получает требуемые квалификаторы точки внедрения
Bean getBean()Получает объект Bean, представляющий компонент, который определяет точку внедрения
Member getMember()Получает объект Field в случае внедрения поля
Annotated getAnnotated()Возвращает Annotated Field или AnnotatedParameter в зависимости от того, относится точка внедрения к полю или параметру метода/конструктора
boolean isDelegate()Определяет, происходит ли в данной точке внедрения подключение делегата декоратора
boolean isTransient()Определяет, является ли точка временным полем


Листинг 2.18. Производитель данных автоматического журнала

>public class LoggingProducer {

>··@Produces

>··private Logger createLogger(InjectionPoint injectionPoint) {

>····return Logger.getLogger(injectionPoint.getMember(). getDeclaringClass(). getName());

>··}

>}

Чтобы использовать произведенный автоматический журнал в любом компоненте, вы просто внедряете его и работаете с ним. Имя класса категории автоматического журнала потом будет задано автоматически:

>@Inject Logger log;

Утилизаторы

В предыдущих примерах (см. листинги 2.17 и 2.18) мы использовали производителей данных для создания типов данных или объектов POJO таким образом, чтобы они могли быть внедрены. Мы создали их, и, пока они использовались, нам не требовалось разрушать или закрывать их. Но некоторые методы производителей данных возвращают объекты, требующие явного разрушения, например интерфейс Java Database Connectivity (JDBC), сеанс JMS или менеджер сущности. Для создания CDI использует производителей данных, а для разрушения — утилизаторы. Метод утилизатора позволяет приложению выполнять настраиваемую очистку объекта, возвращенного методом производителя данных.

Листинг 2.19 показывает утилитный класс, который создает и закрывает интерфейс JDBC. Метод createConnection берет драйвер Derby JDBC, создает соединение с определенным URL, обрабатывает исключения и возвращает открытое соединение JDBC. Это сопровождается аннотацией @Disposes.


Листинг 2.19. Производитель данных и утилизатор соединения JDBC

>public class JDBCConnectionProducer {

>··@Produces

>··private Connection createConnection() {

>····Connection conn = null;

>····try {

>······Class.forName("org.apache.derby.jdbc.EmbeddedDriver"). newInstance();

>······conn = DriverManager.getConnection("jdbc: derby: memory: chapter02DB", 

>"APP", "APP");

>····} catch (InstantiationException | IllegalAccessException | ClassNotFoundException) {

>······e.printStackTrace();

>····}

>····return conn;

>··}

>··private void closeConnection(@Disposes Connection conn) throws SQLException {

>····conn.close();

>··}

>}

Уничтожение может осуществляться путем сопоставления метода утилизатора, определенного тем же классом, что и метод производителя данных. Каждый метод утилизатора, сопровождаемый аннотацией @Disposes, должен иметь строго один параметр такого же типа (тут java.sql.Connection) и квалификаторы (@Default), как соответствующий тип возврата метода производителя данных (с аннотацией @Produces). Метод утилизатора (closeConnection()) вызывается автоматически по окончании контекста клиента (в листинге 2.20 — контекст @ApplicationScoped), и параметр получает объект, порожденный методом производителя данных.


Листинг 2.20. Производитель данных и утилизатор соединения JDBS

>@ApplicationScoped

>public class DerbyPingService {

>··@Inject

>··private Connection conn;

>··public void ping() throws SQLException {

>····conn.createStatement(). executeQuery("SELECT 1 FROM SYSIBM.SYSDUMMY1");

>··}

>}

Листинг 2.20 показывает, как компонент внедряет созданное соединение JDBC с аннотацией @Inject и использует его для проверки доступности базы данных Derby. Как видите, этот клиентский код не занимается всеми вспомогательными задачами по созданию и закрытию соединения JDBC либо обработке исключений. Производители данных и утилизаторы — хороший способ создания и закрытия ресурсов.

Области видимости

CDI имеет отношение не только к внедрению зависимостей, но и к контексту (буква С в аббревиатуре CDI означает контекст). Каждый объект, управляемый CDI, имеет строго определенные область видимости и жизненный цикл, которые связаны с конкретным контекстом. В Java область применения POJO достаточно проста: вы создаете экземпляр класса, используя ключевое слово new, и позволяете сборщику мусора избавиться от него, чтобы освободить некоторое количество памяти. При использовании CDI компонент связан с контекстом и остается в нем до тех пор, пока не будет разрушен контейнером. Удалить компонент из контекста вручную невозможно.


Рекомендуем почитать
Pro Git

Разработчику часто требуется много сторонних инструментов, чтобы создавать и поддерживать проект. Система Git — один из таких инструментов и используется для контроля промежуточных версий вашего приложения, позволяя вам исправлять ошибки, откатывать к старой версии, разрабатывать проект в команде и сливать его потом. В книге вы узнаете об основах работы с Git: установка, ключевые команды, gitHub и многое другое.В книге рассматриваются следующие темы:основы Git;ветвление в Git;Git на сервере;распределённый Git;GitHub;инструменты Git;настройка Git;Git и другие системы контроля версий.


Java 7

Рассмотрено все необходимое для разработки, компиляции, отладки и запуска приложений Java. Изложены практические приемы использования как традиционных, так и новейших конструкций объектно-ориентированного языка Java, графической библиотеки классов Swing, расширенной библиотеки Java 2D, работа со звуком, печать, способы русификации программ. Приведено полное описание нововведений Java SE 7: двоичная запись чисел, строковые варианты разветвлений, "ромбовидный оператор", NIO2, новые средства многопоточности и др.


MFC и OpenGL

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


Симуляция частичной специализации

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


Обработка событий в С++

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


Питон — модули, пакеты, классы, экземпляры

Python - объектно-ориентированный язык сверхвысокого уровня. Python, в отличии от Java, не требует исключительно объектной ориентированности, но классы в Python так просто изучить и так удобно использовать, что даже новые и неискушенные пользователи быстро переходят на ОО-подход.