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

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

>··String generateNumber();

>}

Класс IsbnGenerator (листинг 2.43) сопровождается квалификатором @ThirteenDigits. Это сообщает CDI о том, что сгенерированный номер состоит из 13 цифр. Заметьте, что класс IsbnGenerator также использует внедрение для получения java.util.logging.Logger (произведенного в листинге 2.48) и связывание с перехватчиком @Loggable для регистрации момента входа в метод и выхода из него.


Листинг 2.43. IsbnGenerator генерирует тринадцатизначный номер

>@ThirteenDigits

>public class IsbnGenerator implements NumberGenerator {

>··@Inject

>··private Logger logger;

>··@Loggable

>··public String generateNumber() {

>····String isbn = "13-84356-" + Math.abs(new Random(). nextInt());

>····logger.info("Сгенерирован ISBN: " + isbn);

>····return isbn;

>··}

>}

Класс IssnGenerator в листинге 2.44 — это восьмизначная реализация NumberGenerator.


Листинг 2.44. IssnGenerator генерирует восьмизначный номер

>@EightDigits

>public class IssnGenerator implements NumberGenerator{

>··@Inject

>··private Logger logger;

>··@Loggable

>··public String generateNumber() {

>····String issn = "8-" + Math.abs(new Random(). nextInt());

>····logger.info("Сгенерирован ISBN: " + issn);

>····return issn;

>··}

>}

Класс MockGenerator в листинге 2.45 является альтернативой IsbnGenerator (поскольку также сопровождается квалификатором @ThirteenDigits). MockGenerator используется только для интеграционных тестов, так как его можно активизировать только в файле beans.xml тестовой среды (см. листинг 2.55).


Листинг 2.45. Имитационный генератор чисел, применяемый в качестве альтернативы тринадцатизначного числа

>@Alternative

>@ThirteenDigits

>public class MockGenerator implements NumberGenerator {

>··@Inject

>··private Logger logger;

>··@Loggable

>··public String generateNumber() {

>····String mock = "MOCK-" + Math.abs(new Random(). nextInt());

>····logger.info("Сгенерирован Mock: " + mock);

>····return mock;

>··}

>}

Написание квалификаторов

Поскольку существует несколько реализаций NumberGenerator, CDI необходимо квалифицировать каждый компонент и каждую точку внедрения во избежание неоднозначного внедрения. Для этого он использует два квалификатора: Thirteen Digits (листинг 2.46) и EightDigits (листинг 2.47), оба из которых аннотированы javax.inject.Qualifier и не имеют членов (просто пустые аннотации). Аннотация @ThirteenDigits применяется в компоненте IsbnGenerator (см. листинг 2.43), а также в точке внедрения BookService (см. листинг 2.40).


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

>@Qualifier

>@Retention(RUNTIME)

>@Target({FIELD, TYPE, METHOD})

>public @interface ThirteenDigits { }


Листинг 2.47. Восьмизначный квалификатор

>@Qualifier

>@Retention(RUNTIME)

>@Target({FIELD, TYPE, METHOD})

>public @interface EightDigits { }

Написание автоматического журнала

Демонстрационное приложение использует запись в журнал несколькими способами. Как вы могли видеть в листингах 2.43–2.45, все реализации NumberGenerator применяют внедрение для получения java.util.logging.Logger и записи в журнал. Поскольку Logger входит в состав JDK, он не является внедряемым по умолчанию (архив rt.jar не содержит файла beans.xml) и вам необходимо произвести его. Класс LoggingProducer в листинге 2.48 имеет метод продюсера (produceLogger), аннотированный @Produces. Этот метод создаст и вернет Logger, сопровождаемый параметрами имени класса точки внедрения.


Листинг 2.48. Механизм записи в журнал

>public class LoggingProducer {

>··@Produces

>··public Logger produceLogger(InjectionPoint injectionPoint) {

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

>··}

>}

Класс LoggingInterceptor в листинге 2.49 использует произведенный Logger для регистрации входа в методы и выхода из них. Поскольку запись в журнал может рассматриваться как сквозная функциональность, она отдельно реализуется в виде перехватчика (@AroundInvoke на logMethod). Класс LoggingInterceptor определяет связь с перехватчиком @Loggable (листинг 2.50) и может впоследствии применяться в любом компоненте (например, BookService в листинге 2.40).


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

>@Interceptor

>@Loggable

>public class LoggingInterceptor {

>··@Inject

>··private Logger logger;

>··@AroundInvoke

>··public Object logMethod(InvocationContext ic) throws Exception {

>····logger.entering(ic.getTarget(). getClass(). getName(), 

>ic.getMethod(). getName());

>····try {

>······return ic.proceed();

>····} finally {

>······logger.exiting(ic.getTarget(). getClass(). getName(), 

>ic.getMethod(). getName());

>····}

>··}

>}


Листинг 2.50. Связь с перехватчиком Loggable

>@InterceptorBinding

>@Target({METHOD, TYPE})

>@Retention(RUNTIME)

>public @interface Loggable { }

Написание класса Main

Для запуска демонстрационного приложения нам необходим основной класс (назовем его Main), который приводит в действие контейнер CDI и вызывает метод BookService.createBook. CDI 1.1 не имеет стандартного API для начальной загрузки контейнера, поэтому код в листинге 2.51 специфичен для Weld. В первую очередь он инициализирует WeldContainer и возвращает полностью сконструированную и внедренную сущность BookService.class. Затем вызов метода createBook станет использовать все сервисы контейнера: IsbnGenerator и Logger будут внедрены в BookService с последующим созданием и отображением Book с номером ISBN.


Рекомендуем почитать
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 так просто изучить и так удобно использовать, что даже новые и неискушенные пользователи быстро переходят на ОО-подход.