Изучаем Java EE 7 - [26]
Перехватчики классов
Листинг 2.23 определяет перехватчик, доступный только для CustomerService. Но чаще всего вам требуется изолировать сквозную функциональность в отдельный класс и сообщить контейнеру, чтобы он перехватил вызовы нескольких компонентов. Запись информации в журнал (логирование) — типичный пример ситуации, когда вам требуется, чтобы все методы всех ваших компонентов регистрировали сообщения о входе и выходе. Для указания перехватчика класса вам необходимо разработать отдельный класс и дать контейнеру команду применить его на определенном компоненте или методе компонента.
Чтобы обеспечить совместный доступ к коду множественным компонентам, возьмем методы logMethod() из листинга 2.23 и изолируем их в отдельный класс, как показано в листинге 2.24. Обратите внимание на метод init(), который сопровождается аннотацией @AroundConstruct и будет вызван только вместе с конструктором компонента.
>public class LoggingInterceptor {
>··@Inject
>··private Logger logger;
>··@AroundConstruct
>··private void init(InvocationContext ic) throws Exception {
>····logger.fine("Entering constructor");
>····try {
>······ic.proceed();
>····} finally {
>······logger.fine("Exiting constructor");
>····}
>··}
>··@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());
>····}
>··}
>}
Теперь LoggingInterceptor может быть прозрачно обернут любым компонентом, заинтересованным в этом перехватчике. Для этого компоненту необходимо сообщить контейнеру аннотацию @javax.interceptor.Interceptors. В листинге 2.25 аннотация задается методом createCustomer(). Это означает, что любой вызов этого метода будет перехвачен контейнером, и будет вызван класс LoggingInterceptor (регистрация сообщения на входе в метод и выходе из него).
>@Transactional
>public class CustomerService {
>··@Inject
>··private EntityManager em;
>··@Interceptors(LoggingInterceptor.class)
>··public void createCustomer(Customer customer) {
>····em.persist(customer);
>··}
>··public Customer findCustomerById(Long id) {
>····return em.find(Customer.class, id);
>··}
>}
В листинге 2.25 аннотация @Interceptors прикрепляется только к методу createCustomer(). Это означает, что, если клиент вызывает findCustomerById(), контейнер не будет перехватывать вызов. Если вы хотите, чтобы перехватывались вызовы обоих методов, можете добавить аннотацию @Interceptors либо сразу к обоим методам, либо к самому компоненту. Когда вы это делаете, перехватчик приводится в действие при вызове любого из методов. А поскольку перехватчик имеет аннотацию @AroundConstruct, вызов конструктора тоже будет перехвачен.
>@Transactional
>@Interceptors(LoggingInterceptor.class)
>public class CustomerService {
>··public void createCustomer(Customer customer) {…}
>··public Customer findCustomerById(Long id) {…}
>}
Если ваш компонент имеет несколько методов и вы хотите применить перехватчик ко всему компоненту за исключением определенного метода, можете использовать аннотацию javax.interceptor.ExcludeClassInterceptors для исключения перехвата вызова. В следующем отрывке кода вызов к updateCustomer() не будет перехвачен, а остальные будут:
>@Transactional
>@Interceptors(LoggingInterceptor.class)
>public class CustomerService {
>··public void createCustomer(Customer customer) {…}
>··public Customer findCustomerById(Long id) {…}
>··@ExcludeClassInterceptors
>··public Customer updateCustomer(Customer customer) {… }
>}
Перехватчик жизненного цикла
В начале этой главы я рассказывал о жизненном цикле управляемого компонента (см. рис. 2.2) и событиях обратного вызова. С помощью аннотации обратного вызова вы можете дать контейнеру команду вызвать метод в определенной фазе жизненного цикла (@PostConstruct и @PreDestroy). Например, если вы хотите вносить в журнал запись каждый раз, когда создается экземпляр компонента, вам просто нужно присоединить аннотацию @PostConstruct к методу вашего компонента и добавить к ней некоторые механизмы записи в журнал. Но что, если вам нужно перехватывать события жизненного цикла многих типов компонентов? Перехватчики жизненного цикла позволяют изолировать определенный код в отдельный класс и вызывать его, когда приводится в действие событие жизненного цикла.
Листинг 2.26 демонстрирует класс ProfileInterceptor с двумя методами: logMethod(), который используется для постконструкции, и profile(), применяемый для перехвата методов (@AroundInvoke).
>public class ProfileInterceptor {
>··@Inject
>··private Logger logger;
>··@PostConstruct
>··public void logMethod(InvocationContext ic) throws Exception {
>····logger.fine(ic.getTarget(). toString());
>····try {
>······ic.proceed();
>····} finally {
>······logger.fine(ic.getTarget(). toString());
>····}
>··}
>··@AroundInvoke
>··public Object profile(InvocationContext ic) throws Exception {
Разработчику часто требуется много сторонних инструментов, чтобы создавать и поддерживать проект. Система Git — один из таких инструментов и используется для контроля промежуточных версий вашего приложения, позволяя вам исправлять ошибки, откатывать к старой версии, разрабатывать проект в команде и сливать его потом. В книге вы узнаете об основах работы с Git: установка, ключевые команды, gitHub и многое другое.В книге рассматриваются следующие темы:основы Git;ветвление в Git;Git на сервере;распределённый Git;GitHub;инструменты Git;настройка Git;Git и другие системы контроля версий.
Рассмотрено все необходимое для разработки, компиляции, отладки и запуска приложений Java. Изложены практические приемы использования как традиционных, так и новейших конструкций объектно-ориентированного языка Java, графической библиотеки классов Swing, расширенной библиотеки Java 2D, работа со звуком, печать, способы русификации программ. Приведено полное описание нововведений Java SE 7: двоичная запись чисел, строковые варианты разветвлений, "ромбовидный оператор", NIO2, новые средства многопоточности и др.
В книге рассказывается история главного героя, который сталкивается с различными проблемами и препятствиями на протяжении всего своего путешествия. По пути он встречает множество второстепенных персонажей, которые играют важные роли в истории. Благодаря опыту главного героя книга исследует такие темы, как любовь, потеря, надежда и стойкость. По мере того, как главный герой преодолевает свои трудности, он усваивает ценные уроки жизни и растет как личность.
В книге рассказывается история главного героя, который сталкивается с различными проблемами и препятствиями на протяжении всего своего путешествия. По пути он встречает множество второстепенных персонажей, которые играют важные роли в истории. Благодаря опыту главного героя книга исследует такие темы, как любовь, потеря, надежда и стойкость. По мере того, как главный герой преодолевает свои трудности, он усваивает ценные уроки жизни и растет как личность.
В книге рассказывается история главного героя, который сталкивается с различными проблемами и препятствиями на протяжении всего своего путешествия. По пути он встречает множество второстепенных персонажей, которые играют важные роли в истории. Благодаря опыту главного героя книга исследует такие темы, как любовь, потеря, надежда и стойкость. По мере того, как главный герой преодолевает свои трудности, он усваивает ценные уроки жизни и растет как личность.
Python - объектно-ориентированный язык сверхвысокого уровня. Python, в отличии от Java, не требует исключительно объектной ориентированности, но классы в Python так просто изучить и так удобно использовать, что даже новые и неискушенные пользователи быстро переходят на ОО-подход.