AOP baseado em @AspectJ com Spring
@AspectJ se refere a um estilo de declarar 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/>
Você também precisará das seguintes bibliotecas AspectJ no caminho de classe do seu aplicativo. Essas bibliotecas estão disponíveis no diretório 'lib' de uma instalação do AspectJ, caso contrário, você pode baixá-las da Internet.
- aspectjrt.jar
- aspectjweaver.jar
- aspectj.jar
- aopalliance.jar
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 da seguinte maneira -
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 de pointcut tem duas partes -
Uma expressão pointcut que determina exatamente em quais execuções de método estamos interessados.
Uma assinatura de pointcut que compreende um nome e qualquer número de parâmetros. O corpo real do método é irrelevante e, na verdade, deve estar vazio.
O exemplo a seguir define um ponto de corte denominado 'businessService' que corresponderá à execução de todos os métodos disponíveis nas classes no 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 ponto de corte denominado 'getname' que corresponderá à execução do método getName () disponível na classe Aluno 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 no snippet de código. Isso assume 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 um ponto de corte embutido para qualquer um dos conselhos. A seguir está um exemplo para definir o corte de ponto embutido para antes do conselho -
@Before("execution(* com.xyz.myapp.service.*.*(..))")
public doBeforeTask(){
...
}
Exemplo de AOP baseado em @AspectJ
Para entender os conceitos mencionados acima relacionados ao AOP baseado em @AspectJ, vamos escrever um exemplo que implementará alguns dos conselhos. Para escrever nosso exemplo com alguns conselhos, vamos ter um Eclipse IDE funcionando e realizar as seguintes etapas para criar um aplicativo Spring -
Passos | Descrição |
---|---|
1 | Crie um projeto com um nome SpringExample e crie um pacote com.tutorialspoint sob osrc pasta no projeto criado. |
2 | Adicione as bibliotecas Spring necessárias usando a opção Adicionar JARs externos conforme explicado no capítulo Exemplo do Spring Hello World . |
3 | Adicionar bibliotecas específicas do Spring AOP aspectjrt.jar, aspectjweaver.jar e aspectj.jar no projeto. |
4 | Crie classes Java Logging, Student e MainApp no pacote com.tutorialspoint . |
5 | Crie o arquivo de configuração do Beans Beans.xml sob osrc pasta. |
6 | A etapa final é criar o conteúdo de todos os arquivos Java e do arquivo de configuração do Bean e executar o aplicativo conforme explicado abaixo. |
Aqui está o conteúdo de Logging.javaArquivo. Na verdade, este é um exemplo de módulo de aspecto que define métodos a serem chamados em vários pontos.
package com.tutorialspoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Around;
@Aspect
public class Logging {
/** Following is the definition for a pointcut to select
* all the methods available. So advice will be called
* for all the methods.
*/
@Pointcut("execution(* com.tutorialspoint.*.*(..))")
private void selectAll(){}
/**
* This is the method which I would like to execute
* before a selected method execution.
*/
@Before("selectAll()")
public void beforeAdvice(){
System.out.println("Going to setup student profile.");
}
/**
* This is the method which I would like to execute
* after a selected method execution.
*/
@After("selectAll()")
public void afterAdvice(){
System.out.println("Student profile has been setup.");
}
/**
* This is the method which I would like to execute
* when any method returns.
*/
@AfterReturning(pointcut = "selectAll()", returning = "retVal")
public void afterReturningAdvice(Object retVal){
System.out.println("Returning:" + retVal.toString() );
}
/**
* This is the method which I would like to execute
* if there is an exception raised by any method.
*/
@AfterThrowing(pointcut = "selectAll()", throwing = "ex")
public void AfterThrowingAdvice(IllegalArgumentException ex){
System.out.println("There has been an exception: " + ex.toString());
}
}
A seguir está o conteúdo do Student.java Arquivo
package com.tutorialspoint;
public class Student {
private Integer age;
private String name;
public void setAge(Integer age) {
this.age = age;
}
public Integer getAge() {
System.out.println("Age : " + age );
return age;
}
public void setName(String name) {
this.name = name;
}
public String getName() {
System.out.println("Name : " + name );
return name;
}
public void printThrowException(){
System.out.println("Exception raised");
throw new IllegalArgumentException();
}
}
A seguir está o conteúdo do MainApp.java Arquivo
package com.tutorialspoint;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class MainApp {
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext("Beans.xml");
Student student = (Student) context.getBean("student");
student.getName();
student.getAge();
student.printThrowException();
}
}
A seguir está o arquivo de configuração Beans.xml
<?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 ">
<aop:aspectj-autoproxy/>
<!-- Definition for student bean -->
<bean id = "student" class = "com.tutorialspoint.Student">
<property name = "name" value = "Zara" />
<property name = "age" value = "11"/>
</bean>
<!-- Definition for logging aspect -->
<bean id = "logging" class = "com.tutorialspoint.Logging"/>
</beans>
Quando terminar de criar os arquivos de configuração de origem e bean, vamos executar o aplicativo. Se estiver tudo bem com o seu aplicativo, ele imprimirá a seguinte mensagem -
Going to setup student profile.
Name : Zara
Student profile has been setup.
Returning:Zara
Going to setup student profile.
Age : 11
Student profile has been setup.
Returning:11
Going to setup student profile.
Exception raised
Student profile has been setup.
There has been an exception: java.lang.IllegalArgumentException
.....
other exception content