Spring поддерживает подход стиля аннотации @AspectJ и подход на основе схемы для реализации пользовательских аспектов.
XML на основе схемы
Аспекты реализуются с использованием обычных классов наряду с конфигурацией на основе XML.
Чтобы использовать теги пространства имен AOP, описанные в этом разделе, вам необходимо импортировать схему весеннего AOP, описанную следующим образом:
<?xml version = "1.0" encoding = "UTF-8"?> <beans xmlns = "http://www.springframework.org/schema/beans" xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance" xmlns:aop = "http://www.springframework.org/schema/aop" xsi:schemaLocation = "http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd "> <!-- bean definition & AOP specific configuration --> </beans>
Объявление аспекта
Аспект объявляется с использованием элемента <aop: aspect> , а на компонент поддержки ссылаются с помощью атрибута ref следующим образом.
<aop:config> <aop:aspect id = "myAspect" ref = "aBean"> ... </aop:aspect> </aop:config> <bean id = "aBean" class = "..."> ... </bean>
Здесь «aBean» будет настроен, и зависимость будет внедрена, как и любой другой bean-компонент Spring, как вы видели в предыдущих главах.
Объявление PointCut
PointCut помогает в определении точек соединения (т. Е. Методов ), представляющих интерес для выполнения с различными советами. При работе с конфигурацией на основе XML-схемы PointCut будет определяться следующим образом:
<aop:config> <aop:aspect id = "myAspect" ref = "aBean"> <aop:PointCut id = "businessService" expression = "execution(* com.xyz.myapp.service.*.*(..))"/> ... </aop:aspect> </aop:config> <bean id = "aBean" class = "..."> ... </bean>
В следующем примере определяется PointCut с именем «businessService», который будет соответствовать выполнению метода getName (), доступного в классе Student в пакете com.tutorialspoint.
<aop:config> <aop:aspect id = "myAspect" ref = "aBean"> <aop:PointCut id = "businessService" expression = "execution(* com.tutorialspoint.Student.getName(..))"/> ... </aop:aspect> </aop:config> <bean id = "aBean" class = "..."> ... </bean>
Объявление Советов
Вы можете объявить любой из пяти советов внутри <aop: aspect>, используя элемент <aop: {ADVICE NAME}> следующим образом.
<aop:config> <aop:aspect id = "myAspect" ref = "aBean"> <aop:PointCut id = "businessService" expression = "execution(* com.xyz.myapp.service.*.*(..))"/> <!-- a before advice definition --> <aop:before PointCut-ref = "businessService" method = "doRequiredTask"/> <!-- an after advice definition --> <aop:after PointCut-ref = "businessService" method = "doRequiredTask"/> <!-- an after-returning advice definition --> <!--The doRequiredTask method must have parameter named retVal --> <aop:after-returning PointCut-ref = "businessService" returning = "retVal" method = "doRequiredTask"/> <!-- an after-throwing advice definition --> <!--The doRequiredTask method must have parameter named ex --> <aop:after-throwing PointCut-ref = "businessService" throwing = "ex" method = "doRequiredTask"/> <!-- an around advice definition --> <aop:around PointCut-ref = "businessService" method = "doRequiredTask"/> ... </aop:aspect> </aop:config> <bean id = "aBean" class = "..."> ... </bean>
Вы можете использовать один и тот же doRequiredTask или разные методы для разных советов. Эти методы будут определены как часть аспектного модуля.
На основе @AspectJ
@AspectJ относится к стилю объявления аспектов как обычных классов Java, аннотированных аннотациями Java 5. @AspectJ относится к стилю объявления аспектов как обычных классов Java, аннотированных аннотациями Java 5. Поддержка @AspectJ включается включением следующего элемента в файл конфигурации на основе XML-схемы.
<aop:aspectj-autoproxy/>
Объявление аспекта
Классы аспектов похожи на любой другой нормальный компонент и могут иметь методы и поля, как и любой другой класс, за исключением того, что они будут помечены @Aspect следующим образом.
package org.xyz; import org.aspectj.lang.annotation.Aspect; @Aspect public class AspectModule { }
Они будут настроены в XML как любой другой компонент следующим образом.
<bean id = "myAspect" class = "org.xyz.AspectModule"> <!-- configure properties of aspect here as normal --> </bean>
Объявление PointCut
PointCut помогает в определении точек соединения (т. Е. Методов ), представляющих интерес для выполнения с различными советами. При работе с конфигурацией на основе @AspectJ объявление PointCut состоит из двух частей:
-
Выражение PointCut, которое точно определяет, какие методы выполнения нас интересуют.
-
Подпись PointCut, содержащая имя и любое количество параметров. Фактическое тело метода не имеет значения и фактически должно быть пустым.
Выражение PointCut, которое точно определяет, какие методы выполнения нас интересуют.
Подпись PointCut, содержащая имя и любое количество параметров. Фактическое тело метода не имеет значения и фактически должно быть пустым.
В следующем примере определяется PointCut с именем «businessService», который будет соответствовать выполнению каждого метода, доступного в классах в пакете com.xyz.myapp.service.
import org.aspectj.lang.annotation.PointCut; @PointCut("execution(* com.xyz.myapp.service.*.*(..))") // expression private void businessService() {} // signature
В следующем примере определяется PointCut с именем ‘getname’, который будет соответствовать выполнению метода getName (), доступного в классе Student в пакете com.tutorialspoint.
import org.aspectj.lang.annotation.PointCut; @PointCut("execution(* com.tutorialspoint.Student.getName(..))") private void getname() {}
Объявление Советов
Вы можете объявить любой из пяти советов, используя аннотации @ {ADVICE-NAME}, как указано ниже. Это предполагает, что вы уже определили метод подписи PointCut businessService ().
@Before("businessService()") public void doBeforeTask(){ ... } @After("businessService()") public void doAfterTask(){ ... } @AfterReturning(PointCut = "businessService()", returning = "retVal") public void doAfterReturnningTask(Object retVal){ // you can intercept retVal here. ... } @AfterThrowing(PointCut = "businessService()", throwing = "ex") public void doAfterThrowingTask(Exception ex){ // you can intercept thrown exception here. ... } @Around("businessService()") public void doAroundTask(){ ... }
Вы можете определить PointCut inline для любого из советов. Ниже приведен пример определения встроенного PointCut для перед рекомендацией.