Spring AOP - Implementações
Spring apóia o @AspectJ annotation style abordagem e o schema-based abordagem para implementar aspectos personalizados.
Com base em esquema XML
Aspectos são implementados usando classes regulares junto com configuração baseada em XML.
Para usar as tags de namespace AOP descritas nesta seção, você precisa importar o esquema AOP spring, descrito a seguir -
<?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>
Declarando um Aspecto
A aspect é declarado usando o <aop:aspect> elemento, e o bean de apoio é referenciado usando o ref atributo da seguinte forma.
<aop:config>
<aop:aspect id = "myAspect" ref = "aBean">
...
</aop:aspect>
</aop:config>
<bean id = "aBean" class = "...">
...
</bean>
Aqui, "aBean" será configurado e a dependência injetada como qualquer outro bean Spring, como você viu nos capítulos anteriores.
Declarando um PointCut
UMA PointCutajuda a determinar os pontos de junção (ou seja, métodos) de interesse a serem executados com diferentes conselhos. Ao trabalhar com a configuração baseada no esquema XML, PointCut será definido da seguinte forma -
<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>
O exemplo a seguir define um PointCut denominado 'businessService' que corresponderá à execução do método getName () disponível na classe Aluno no pacote 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>
Declarando Conselhos
Você pode declarar qualquer um dos cinco conselhos dentro de um <aop: aspect> usando o elemento <aop: {ADVICE NAME}> como segue.
<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>
Você pode usar o mesmo doRequiredTaskou métodos diferentes para conselhos diferentes. Esses métodos serão definidos como parte do módulo de aspecto.
Baseado em @AspectJ
@AspectJ refere-se a um estilo de declaração de aspectos como classes Java regulares anotadas com anotações Java 5. O suporte @AspectJ é habilitado incluindo o seguinte elemento dentro de seu arquivo de configuração baseado em esquema XML.
<aop:aspectj-autoproxy/>
Declarando um Aspecto
As classes de aspectos são como qualquer outro bean normal e podem ter métodos e campos como qualquer outra classe, exceto que eles serão anotados com @Aspect como segue.
package org.xyz;
import org.aspectj.lang.annotation.Aspect;
@Aspect
public class AspectModule {
}
Eles serão configurados em XML como qualquer outro bean da seguinte maneira.
<bean id = "myAspect" class = "org.xyz.AspectModule">
<!-- configure properties of aspect here as normal -->
</bean>
Declarando um PointCut
UMA PointCutajuda a determinar os pontos de junção (ou seja, métodos) de interesse a serem executados com diferentes conselhos. Ao trabalhar com a configuração baseada em @AspectJ, a declaração PointCut tem duas partes -
Uma expressão PointCut que determina exatamente em quais execuções de método estamos interessados.
Uma assinatura PointCut que compreende um nome e qualquer número de parâmetros. O corpo real do método é irrelevante e, na verdade, deveria estar vazio.
O exemplo a seguir define um PointCut denominado 'businessService' que corresponderá à execução de cada método disponível nas classes sob o pacote com.xyz.myapp.service.
import org.aspectj.lang.annotation.PointCut;
@PointCut("execution(* com.xyz.myapp.service.*.*(..))") // expression
private void businessService() {} // signature
O exemplo a seguir define um PointCut denominado 'getname' que corresponderá à execução do método getName () disponível na classe Student no pacote com.tutorialspoint.
import org.aspectj.lang.annotation.PointCut;
@PointCut("execution(* com.tutorialspoint.Student.getName(..))")
private void getname() {}
Declarando Conselhos
Você pode declarar qualquer um dos cinco avisos usando as anotações @ {ADVICE-NAME} conforme fornecido abaixo. Isso pressupõe que você já definiu um método de assinatura 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(){
...
}
Você pode definir PointCut embutido para qualquer um dos conselhos. A seguir está um exemplo para definir PointCut embutido para aconselhamento prévio.
@Before("execution(* com.xyz.myapp.service.*.*(..))")
public doBeforeTask(){
...
}