Главная » Spring » Объявление советов, выполняемых и до, и после Spring

0

Текущая реализация класса Audience работает замечательно. Но простые советы, выполняемые до или после вызова метода, имеют некоторые ограничения. В частности, довольно сложно обеспечить совместное использование информации советами, выполняемыми до или после, не прибегая к использованию переменных экземпляра.

Например, предположим, что к выключению сотовых телефонов и аплодисментов в конце также было бы желательно, чтобы зрители посматривали на часы и отмечали продолжительность выступления. Единственный способ решить эту задачу – использовать совет, вы- полняемый до и после, чтобы перед выступлением засечь текущее время, а после выступления определить его продолжительность. Но при этом придется сохранить время начала в переменной экземпля- ра. Поскольку экземпляр класса Audience – единственный в прило- жении, он не может использоваться в многопоточной среде выпол- нения без риска повредить хранимые в нем данные.

В этом отношении совет, выполняемый и до, и после вызова це- левого метода, имеет преимущество перед советами, выполняемыми до или после. Он позволяет решать те же задачи, что и советы, вы- полняемые до или после, но делает это в единственном методе. А так как совет целиком выполняется в рамках единственного метода, нет необходимости сохранять промежуточные данные в переменных эк- земпляра.

Например, взгляните на новый метод watchPerformance(), представ- ленный в листинге 5.4.

Листинг 4.4. Метод watchPerformance() реализует совет AOP, выполняемый и до, и после вызова целевого метода

public void watchPerformance(ProceedingJoinPoint joinpoint) { try  {

System.out.println("The audience is taking their seats."); System.out.println("The audience is turning off their cellphones"); long start = System.currentTimeMillis(); // Перед выступлением

joinpoint.proceed();                                   // Вызов  целевого  метода long end = System.currentTimeMillis();   // После выступления

System.out.println("CLAP   CLAP   CLAP   CLAP   CLAP");

System.out.println("The performance took " + (end – start)

+   "   milliseconds.");

} catch (Throwable t) {

System.out.println("Boo!   We   want   our   money   back!");

}

}

Первое, на что следует обратить внимание в реализации нового совета, – он принимает параметр типа ProceedingJoinPoint. Этот объ- ект необходим для вызова целевого метода внутри совета. Метод со- вета выполнит все необходимые предварительные операции и, когда будет готов передать управление целевому методу, вызовет метод ProceedingJoinPoint.proceed().

Имейте в виду, что крайне важно не забывать включать вызов ме- тода proceed(). Если этого не сделать, совет фактически заблокирует доступ к целевому методу. Возможно, в некоторых случаях именно это и требуется, но чаще бывает желательно, чтобы целевой метод был выполнен в какой-то момент.

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

В примере с аспектом audience метод watchPerformance() реализу- ет все, что было реализовано в четырех прежних методах совета, но теперь все это сосредоточено в единственном методе, и он не- сет полную ответственность за обработку ошибок. Обратите также внимание, что непосредственно перед вызовом метода proceed(), со- ответствующего точке сопряжения, в локальной переменной сохра-

няется текущее время. Сразу после возврата из метода выводится длительность выступления.

Объявление совета, выполняющегося и до, и после целевого мето- да, мало отличается от объявлений советов других типов, достаточно просто использовать элемент <aop:around>, как показано в листинге 5.5.

Листинг 5.5. Определение аспекта audience с единственным советом, выполняемым и до, и после вызова целевого метода

<aop:config>

<aop:aspect ref="audience">

<aop:pointcut  id="performance2"  expression=

"execution(*  com.springinaction.springidol.Performer.perform(..))"

/>

<!–  Совет,  выполняемый  и  до,  и  после  –>

<aop:around

pointcut-ref="performance2" method="watchPerformance()" />

</aop:aspect>

</aop:config>

Подобно другим XML-элементам определения советов, в элементе

<aop:around> указываются срез множества точек сопряжения и имя ме- тода, реализующего совет. Здесь используется тот же срез, что и преж- де, но в атрибуте method указано имя нового метода watchPerformance().

Источник:   Уоллс К., Spring в действии. – М.: ДМК Пресс, 2013. – 752 с.: ил.

По теме:

  • Комментарии