AOP basato su XML Schema con Spring

Per utilizzare i tag dello spazio dei nomi AOP descritti in questa sezione, è necessario importare lo schema springAOP come descritto:

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

Avrai anche bisogno delle seguenti librerie AspectJ sul CLASSPATH della tua applicazione. Queste librerie sono disponibili nella directory "lib" di un'installazione di AspectJ, altrimenti è possibile scaricarle da Internet.

  • aspectjrt.jar
  • aspectjweaver.jar
  • aspectj.jar
  • aopalliance.jar

Dichiarare un aspetto

Un aspect viene dichiarato utilizzando il <aop:aspect> elemento e il backing bean viene referenziato utilizzando il ref attributo come segue -

<aop:config>
   <aop:aspect id = "myAspect" ref = "aBean">
      ...
   </aop:aspect>
</aop:config>

<bean id = "aBean" class = "...">
   ...
</bean>

Qui verrà configurato "aBean" e verrà iniettata la dipendenza proprio come qualsiasi altro bean Spring come si è visto nei capitoli precedenti.

Dichiarare un taglio a punti

UN pointcutaiuta a determinare i punti di unione (cioè i metodi) di interesse da eseguire con diversi consigli. Mentre si lavora con la configurazione basata su XML Schema, pointcut sarà definito come segue:

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

Il seguente esempio definisce un pointcut denominato 'businessService' che corrisponderà all'esecuzione del metodo getName () disponibile nella classe Student nel pacchetto 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>

Dichiarare consigli

Puoi dichiarare uno qualsiasi dei cinque consigli all'interno di un <aop: aspect> utilizzando l'elemento <aop: {ADVICE NAME}> come indicato di seguito -

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

Puoi usare lo stesso doRequiredTasko metodi diversi per consigli diversi. Questi metodi saranno definiti come parte del modulo di aspetto.

Esempio di AOP basato su XML Schema

Per comprendere i concetti sopra menzionati relativi all'AOP basato su XML Schema, scriviamo un esempio che implementerà alcuni dei consigli. Per scrivere il nostro esempio con pochi consigli, disponiamo di un IDE Eclipse funzionante e seguiamo i seguenti passaggi per creare un'applicazione Spring:

Passo Descrizione
1 Crea un progetto con un nome SpringExample e crea un pacchetto com.tutorialspoint sottosrc cartella nel progetto creato.
2 Aggiungere le librerie Spring richieste utilizzando l' opzione Aggiungi JAR esterni come spiegato nel capitolo Esempio Spring Hello World .
3 Aggiungi librerie specifiche per Spring AOP aspectjrt.jar, aspectjweaver.jar e aspectj.jar nel progetto.
4 Crea classi Java Logging, Student e MainApp nel pacchetto com.tutorialspoint .
5 Crea il file di configurazione Beans Beans.xml sottosrc cartella.
6 Il passaggio finale consiste nel creare il contenuto di tutti i file Java e nel file di configurazione Bean ed eseguire l'applicazione come spiegato di seguito.

Ecco il contenuto di Logging.javafile. Questo è in realtà un esempio di modulo di aspetto che definisce i metodi da chiamare in vari punti.

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());   
   }
}

Di seguito è riportato il contenuto del file Student.java file

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();
   }
}

Di seguito è riportato il contenuto del file MainApp.java file

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();
   }
}

Di seguito è riportato il file di configurazione 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>

Una volta terminata la creazione dei file di configurazione dei bean e dei sorgenti, eseguiamo l'applicazione. Se tutto va bene con la tua applicazione, stamperà il seguente messaggio:

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

Il <aop: pointcut> sopra definito seleziona tutti i metodi definiti nel pacchetto com.tutorialspoint. Supponiamo che tu voglia eseguire il tuo consiglio prima o dopo un particolare metodo, puoi definire il tuo pointcut per restringere la tua esecuzione sostituendo le stelle (*) nella definizione pointcut con i nomi effettivi della classe e del metodo. Di seguito è riportato un file di configurazione XML modificato per mostrare il concetto:

<?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 si esegue l'applicazione di esempio con queste modifiche alla configurazione, verrà stampato il seguente messaggio:

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