Spring AOP - Wdrożenia
Wiosna wspiera @AspectJ annotation style podejście i schema-based podejście do wdrażania niestandardowych aspektów.
Oparte na schemacie XML
Aspekty są implementowane przy użyciu zwykłych klas wraz z konfiguracją opartą na XML.
Aby użyć tagów przestrzeni nazw AOP opisanych w tej sekcji, musisz zaimportować schemat sprężynowego AOP, opisany w następujący sposób -
<?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>
Deklarowanie aspektu
Na aspect jest deklarowana przy użyciu <aop:aspect> element, a do fasoli zapasowej odwołuje się przy użyciu ref atrybut w następujący sposób.
<aop:config>
<aop:aspect id = "myAspect" ref = "aBean">
...
</aop:aspect>
</aop:config>
<bean id = "aBean" class = "...">
...
</bean>
Tutaj "aBean" zostanie skonfigurowany i wstawiony zależność tak, jak każdy inny bean Spring, jak widzieliśmy w poprzednich rozdziałach.
Deklarowanie PointCut
ZA PointCutpomaga w określaniu punktów złączenia (tj. metod), które mają być wykonane, z różnymi radami. Podczas pracy z konfiguracją opartą na schemacie XML PointCut zostanie zdefiniowany w następujący sposób -
<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>
Poniższy przykład definiuje PointCut o nazwie „businessService”, który będzie pasował do metody getName () dostępnej w klasie Student w pakiecie 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>
Deklarowanie porad
Możesz zadeklarować dowolną z pięciu porad wewnątrz <aop: aspekt> za pomocą elementu <aop: {NAZWA PORADY}> w następujący sposób.
<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>
Możesz użyć tego samego doRequiredTasklub różne metody dla różnych porad. Metody te zostaną zdefiniowane jako część modułu aspektów.
Oparty na @AspectJ
@AspectJ odnosi się do stylu deklarowania aspektów jako zwykłych klas Java z adnotacjami Java 5. Obsługa @AspectJ jest włączana przez dołączenie następującego elementu do pliku konfiguracyjnego opartego na schemacie XML.
<aop:aspectj-autoproxy/>
Deklarowanie aspektu
Klasy aspektu są jak każdy inny normalny bean i mogą mieć metody i pola tak jak każda inna klasa, z tym wyjątkiem, że zostaną opatrzone adnotacją @Aspect w następujący sposób.
package org.xyz;
import org.aspectj.lang.annotation.Aspect;
@Aspect
public class AspectModule {
}
Zostaną skonfigurowane w XML, jak każdy inny bean w następujący sposób.
<bean id = "myAspect" class = "org.xyz.AspectModule">
<!-- configure properties of aspect here as normal -->
</bean>
Deklarowanie PointCut
ZA PointCutpomaga w określaniu punktów złączenia (tj. metod), które mają być wykonane, z różnymi radami. Podczas pracy z konfiguracją opartą na @AspectJ deklaracja PointCut składa się z dwóch części -
Wyrażenie PointCut, które dokładnie określa, które wykonania metod nas interesują.
Podpis PointCut zawierający nazwę i dowolną liczbę parametrów. Rzeczywista treść metody jest nieistotna i w rzeczywistości powinna być pusta.
Poniższy przykład definiuje PointCut o nazwie „businessService”, który będzie zgodny z wykonaniem każdej metody dostępnej w klasach w pakiecie com.xyz.myapp.service.
import org.aspectj.lang.annotation.PointCut;
@PointCut("execution(* com.xyz.myapp.service.*.*(..))") // expression
private void businessService() {} // signature
Poniższy przykład definiuje PointCut o nazwie „getname”, który będzie pasował do metody getName () dostępnej w klasie Student w pakiecie com.tutorialspoint.
import org.aspectj.lang.annotation.PointCut;
@PointCut("execution(* com.tutorialspoint.Student.getName(..))")
private void getname() {}
Deklarowanie porad
Możesz zadeklarować dowolną z pięciu porad, używając adnotacji @ {ADVICE-NAME}, jak podano poniżej. Zakłada się, że zdefiniowano już metodę podpisu BusinessService () PointCut.
@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(){
...
}
Możesz zdefiniować PointCut inline dla dowolnej porady. Poniżej znajduje się przykład definiowania inline PointCut przed poradą.
@Before("execution(* com.xyz.myapp.service.*.*(..))")
public doBeforeTask(){
...
}