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

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

>····long initTime = System.currentTimeMillis();

>····try {

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

>····} finally {

>······long diffTime = System.currentTimeMillis() — initTime;

>······logger.fine(ic.getMethod() + " took " + diffTime + " millis");

>····}

>··}

>}

Как видно из листинга 2.26, перехватчики жизненного цикла берут параметр InvocationContext и вместо Object возвращают void. Чтобы применить перехватчик, определенный в листинге 2.26, компонент CustomerService (листинг 2.27) должен использовать аннотацию @Interceptors и определять ProfileInterceptor. Если компонент инстанцируется контейнером, метод logMethod() будет вызван раньше метода init(). Затем, если клиент вызывает createCustomer() или findCustomerById(), будет вызван метод profile().


Листинг 2.27. CustomerService, использующий перехватчик и аннотацию обратного вызова

>@Transactional

>@Interceptors(ProfileInterceptor.class)

>public class CustomerService {

>··@Inject

>··private EntityManager em;

>··@PostConstruct

>··public void init() {

>····//…

>··}

>··public void createCustomer(Customer customer) {

>····em.persist(customer);

>··}

>··public Customer findCustomerById(Long id) {

>····return em.find(Customer.class, id);

>··}

>}

Связывание и исключение перехватчиков

Вы уже видели, как перехватываются вызовы в пределах одного компонента (с аннотацией @Around Invoke), а также среди множественных компонентов (с использованием аннотации @Interceptors). Спецификация Interceptors 1.2 также позволяет связать в цепочку несколько перехватчиков.

В действительности аннотация @Interceptors способна прикреплять более одного перехватчика, так как в качестве параметра она берет список перехватчиков, разделенных запятой. Когда определяются множественные перехватчики, порядок их вызова задается тем порядком, в котором они указаны в аннотации @Interceptors. Например, код в листинге 2.28 использует аннотацию @Interceptors у компонента и на уровне методов.


Листинг 2.28. CustomerService, соединяющий несколько перехватчиков

>@Stateless

>@Interceptors({I1.class, I2.class})

>public class CustomerService {

>··public void createCustomer(Customer customer) {…}

>··@Interceptors({I3.class, I4.class})

>··public Customer findCustomerById(Long id) {…}

>··public void removeCustomer(Customer customer) {…}

>··@ExcludeClassInterceptors

>··public Customer updateCustomer(Customer customer) {…}

>}

Когда клиент вызывает метод updateCustomer(), перехватчик не вызывается, так как метод аннотирован @ExcludeClassInterceptors. При вызове метода createCustomer() выполняется перехватчик I1, за которым следует перехватчик I2. При вызове метода findCustomerById() перехватчики I1, I2, I3 и I4 выполняются в соответствующем порядке.

Связывание с перехватчиком

Перехватчики определяются в своей собственной спецификации (запрос JSR 318) и могут использоваться в любых управляемых компонентах (EJB, сервлетах, веб-службах RESTful и т. д.). Но CDI расширил исходную спецификацию, добавив к ней связывание с перехватчиком. Это означает, что связывание с перехватчиком может применяться только тогда, когда активизирован CDI.

Если вы посмотрите на листинг 2.25, то увидите, как работают перехватчики. Реализацию перехватчика необходимо указывать непосредственно на реализации компонента (например, @Interceptors(LoggingInterceptror.class)). Это типобезопасно, но нет слабой связи. CDI обеспечивает связывание с перехватчиком, которое представляет определенный уровень косвенности и слабой связанности. Тип связывания с перехватчиком — это определенная пользователем аннотация, также сопровождаемая аннотацией @InterceptorBinding, которая связывает класс перехватчика с компонентом без прямой зависимости между этими двумя классами.

Листинг 2.29 показывает связывание с перехватчиком под названием Loggable. Как видите, данный код очень похож на квалификатор. Связывание с перехватчиком — это аннотация, также аннотированная @InterceptorBinding, которая может быть пустой или иметь члены (например, как в листинге 2.13).


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

>@InterceptorBinding

>@Target({METHOD, TYPE})

>@Retention(RUNTIME)

>public @interface Loggable { }

При наличии связывания с перехватчиком необходимо прикрепить его к самому перехватчику. Для этого к перехватчику добавляется аннотация @Interceptor и связывание с перехватчиком (Loggable в листинге 2.30).


Листинг 2.30. Перехватчик Loggable

>@Interceptor

>@Loggable

>public class LoggingInterceptor {

>··@Inject

>··private Logger logger;

>··@AroundInvoke

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

>····logger.entering(ic.getTarget(). toString(), ic.getMethod(). getName());

>····try {

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

>····} finally {

>······logger.exiting(ic.getTarget(). toString(), ic.getMethod(). getName());

>····}

>··}

>}

Теперь вы можете применить перехватчик к компоненту, проаннотировав класс компонента той же связкой перехватчиков, которая показана в листинге 2.31. Это дает вам слабую связанность (так как класс реализации явно не указывается) и неплохой уровень косвенности.


Листинг 2.31. CustomerService, использующий связку перехватчиков

>@Transactional

>@Loggable

>public class CustomerService {


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