AOP baseado em esquema XML com Spring

Para usar as tags de namespace AOP descritas nesta seção, você precisa importar o esquema springAOP conforme descrito -

<?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>

Você também precisará das seguintes bibliotecas AspectJ no CLASSPATH de 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

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, o 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 ponto de corte 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}> conforme fornecido abaixo -

<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.

Exemplo de AOP baseado em esquema XML

Para entender os conceitos mencionados acima relacionados ao AOP baseado em XML Schema, 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 -

Degrau 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. Este é realmente um exemplo de módulo de aspecto que define os métodos a serem chamados em vários pontos.

package com.tutorialspoint;

public class Logging {
   /** 
      * This is the method which I would like to execute
      * before a selected method execution.
   */
   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.
   */
   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.
   */
   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.
   */
   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:config>
      <aop:aspect id = "log" ref = "logging">
         <aop:pointcut id = "selectAll" 
            expression = "execution(* com.tutorialspoint.*.*(..))"/>
         
         <aop:before pointcut-ref = "selectAll" method = "beforeAdvice"/>
         <aop:after pointcut-ref = "selectAll" method = "afterAdvice"/>
         <aop:after-returning pointcut-ref = "selectAll" 
            returning = "retVal" method = "afterReturningAdvice"/>
         
         <aop:after-throwing pointcut-ref = "selectAll" 
            throwing = "ex" method = "AfterThrowingAdvice"/>
      </aop:aspect>
   </aop:config>

   <!-- 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>

Assim que terminar de criar os arquivos de configuração de código-fonte e bean, vamos executar o aplicativo. Se tudo estiver bem com 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

O <aop: pointcut> definido acima seleciona todos os métodos definidos no pacote com.tutorialspoint. Vamos supor que você deseja executar seu conselho antes ou depois de um método específico, você pode definir seu pointcut para restringir sua execução substituindo as estrelas (*) na definição de pointcut pelos nomes reais da classe e do método. A seguir está um arquivo de configuração XML modificado para mostrar o conceito -

<?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:config>
      <aop:aspect id = "log" ref = "logging">
         <aop:pointcut id = "selectAll" 
            expression = "execution(* com.tutorialspoint.Student.getName(..))"/>
         <aop:before pointcut-ref = "selectAll" method = "beforeAdvice"/>
         <aop:after pointcut-ref = "selectAll" method = "afterAdvice"/>
      </aop:aspect>
   </aop:config>

   <!-- 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>

Se você executar o aplicativo de amostra com essas alterações de configuração, ele imprimirá a seguinte mensagem -

Going to setup student profile.
Name : Zara
Student profile has been setup.
Age : 11
Exception raised
.....
other exception content