Interceptors Василий Кряжев
Рассматриваемые темы Перехват методов бизнес интерфейса Перехват событий жизненного цикла Interceptors и обработка исключений 1-2
Рассматриваемые темы Перехват методов бизнес интерфейса Создание interceptor класса Применение interceptors Перехват событий жизненного цикла Interceptors и обработка исключений 1-3
Что public class TodoListBean { public void assignProject(Project project) { long start = System.currentTimeMillis(); try { // реализация бизнес логики } finally { long stop = System.currentTimeMillis(); log.write(assignProject: + (stop - start) + (ms)); } Код профилирования загрязняет бизнес логику 1-4
Interceptor методы AroundInvoke {} // Сигнатура метода помеченного Object method-name(javax.interceptor.InvocationContext invocationContext) throws Exception; Декларирование 1-5
Interceptor класс public class BeanProfiler public Object timeMethod( InvocationContext ctx) throws Exception { long start = System.currentTimeMillis(); try { return ctx.proceed(); } finally { long stop = System.currentTimeMillis(); log.write(assignProject: + (stop - start) + (ms)); } Код профилирования после рефакторинга 1-6
Контекст выполнения package javax.interceptor; public interface InvocationContext { java.lang.Object getTarget(); java.lang.reflect.Method getMethod(); java.lang.Object[] getParameters(); void setParameters(java.lang.Object[] objects); java.util.Map getContextData(); java.lang.Object proceed() throws java.lang.Exception; } getContextData – данные которые можно совместно использовать в процессе вызова бизнес метода proceed – запускает следующий interceptor метод или сам бизнес метод в конце цепочки Интерфейс InvocationContext 1-7
Применение interceptors package Interceptors { java.lang.Class[] // на уровне класса, для всех методов public class TodoListBean { public class TodoListBean // на уровне метода public void assignProject(Project project){…} } Применение на основе аннотаций: 1-8
Применение interceptors TodoListBean com.acme.BeanProfiler TodoListBean com.acme.BeanProfiler assignProject com.acme.Project Применение через дескриптор развертывания: 1-9
Interceptors по умолчанию * com.acme.Logger TodoListBean com.acme.BeanProfiler Применение interceptor для всех бинов модуля ejb-jar используя символ * 1-10
Interceptors по умолчанию * com.acme.Logger TodoListBean com.acme.BeanProfiler Отключение перехватчиков назначенных по умолчанию 1-11
Interceptors и public class AccessInterceptor EJBContext = ACCESS_DB) EntityManager public Object record(InvocationContext ctx) throws Exception { AccessRecord record = new AccessRecord(new Date(), ejbContext.getCallerPrincipal(), ejbContext.getMethod()); try{ ctx.proceed(); } catch (Exception e) { record.setError(e); throw e; } finally { em.pertsist(record); } Инициализация ссылок через DI 1-12
Выводы Создавать interceptor классы и AroundInvoke методы Связывать interceptors с классами и методами EJB Декларировать interceptors используемые по умолчанию Инициализировать в interceptor классах ссылки на ресурсы В этой секции мы узнали как: 1-13
Рассматриваемые темы Перехват методов бизнес интерфейса Перехват событий жизненного цикла Interceptors и обработка исключений 1-14
События жизненного public class OrderAgentBean implements OrderAgentRemote, OrderAgentLocal public void initialize() { // obtain connections, files, streams public void cleanup() { // close connections, files, streams } Аннотации жизненного цикла 1-15 см. далее
События жизненного цикла PrePassivate PostActivate Сигнатура метода обработки события жизненного цикла в классе реализации идет без параметров и без блока void metod-name(); Аннотации жизненного цикла 1-16
События жизненного цикла Сигнатура метода обработки события жизненного цикла в interceptor void metod-name(InvocationContext ctx); В interceptor классе может быть только один метод для обработки события каждого типа Обработка событий в Interceptor классе 1-17
События public class ShoppingCartBean implements ShoppingCart public void startShoppingCart() { … } public int someShoppingMethod() { … } } public class AccessInterceptor public void startAccessEvent(InvocationContext ctx) { // какие либо действия ctx.proceed(); public Object record(InvocationContext ctx) { // какие либо действия ctx.proceed(); } Пример цепочки событий 1-18
Рассматриваемые темы Перехват методов бизнес интерфейса Перехват событий жизненного цикла Interceptors и обработка исключений 1-19
Обработка исключений public class String public Object tryAlternateUrl(InvocationContext ctx) throws Exception { try { return ctx.proceed(); } catch (javax.naming.ServiceUnavailableException e) { Object[] newArgs = ctx.getParameters(); newArgs[0] = alternateUrl; ctx.setParameters(newArgs); return ctx.proceed(); } Изменение параметров вызова 1-20
Обработка исключений public class WithdrawalValidator int public Object validate(InvocationContext ctx) throws Exception { int amount = ctx.getParameters()[0]; if (amount > maxUnapprovedDebit) throw new DebitLimitException(Amount: + amount); return ctx.proceed(); } Прекращение дальнейшей обработки 1-21
Обработка = true) public class DbDeadlockException extends java.sql.SQLException { … } public class SybaseErrorHandler public Object narrowSQLException(InvocationContext ctx) throws Exception { try { return ctx.proceed(); } catch (SQLException e) { int errorCode = e.getErrorCode(); switch (errorCode) { case 1205: throw new DbDeadlockException(e); case 557: throw new DbInvalidCursorException(e); } Преобразование исключений 1-22
Выводы Ловить и обрабатывать исключения в AroundInvoke методах Использовать interceptors чтобы предотвратить вызов бизнес метода Использовать interceptors для преобразования исключений В этой секции мы узнали как: 1-23
Практика Вынос общего поведения в EJB interceptor Упражнение 1-24
Выводы Создавать и использовать interceptor классы в EJB Создавать interceptors для обработки событий жизненного цикла Использовать interceptors при обработке исключений В этом модуле мы узнали как: 1-25