Spring AOP

Vediamo come l’AOP (Aspect Oriented Programming) può essere utilizzato nei nostri progetti, attraverso Spring AOP.

AOP for dummies

AOP (Aspect Oriented Programming) è un paradigma di sviluppo che introduce il concetto di “aspetto” nello sviluppo software. Possiamo identificare l’aspetto con qualcosa di trasversale alle nostri componenti software, qualcosa che comunque viene impiegato in maniera simile in diversi punti e che non coinvolge direttamente la logica di business del nostro componente

AOP

 

I classici esempi che vengono utilizzati nella “letteratura AOP” sono il logging, la connessione ai database, le transazioni etc. etc. Queste funzionalità sono tendenzialmente trasversali al nostro software, vengono richiamate in diversi punti e chiaramente non sono il “core business” delle nostre componenti software, ma degli aspetti trasversali che utilizziamo. Se analizziamo un nostro componente di business, possiamo identificare una serie di aspetti trasversali e isolandoli vediamo che poi la logica vera e propria è ristretta in una parte minore del nostro componente.

AOP 2

 

Oltre ai classici esempi di aspetti che vengono illustrati, dobbiamo chiaramente ampliare il discorso al business della nostra applicazione per renderci conto degli effettivi benefici che potrebbe introdurre questo paradigma di sviluppo. Immaginiamo che la nostra applicazione gestisca dei clienti di tipo A, B e C. Su questi clienti vengono effettuate una serie di operazioni differenti, ma alla base di ogni funzionalità abbiamo comunque la necessità di reperire le informazioni complete di questo cliente.

Questo potrebbe essere un aspetto della nostra applicazione, ovvero il fatto di operare su informazioni complete di un cliente è un aspetto trasversale a tutte le funzionalità del nostro software, quindi può essere gestito in maniera univoca ed essere applicato nei punti di interesse dei nostri componenti.

 

Spring AOP

Spring basa tutte le sue funzionalità sul paradigma del Dependency injection (una tecnica di IoC, Inversion of control) che permette di slegare la creazione e le dipendenze relative ad un oggetto. In un framework simile l’utilizzo di AOP è chiaramente consigliato, anche perchè questo paradigma è un ulteriore modo per creare un basso accoppiamento tra le funzionalità del nostro software.

In Spring possiamo utilizzare diverse tecniche per implementare l’AOP, alcune derivanti da una vecchia versione di API della 1.2, altre nuove introdotte con la 2.0 oppure sfruttando direttamente il supporto di AspectJ, una libreria che permette di definire gli aspetti con una sua sintassi particolare. Prima di sporcarci le mani con codice e configurazioni dobbiamo però capire alcune terminologie chiave dell’AOP, presenti anche in Spring.

AOP 3

 

Nell’immagine precedente vengono riportate alcuni termini dell’AOP che dobbiamo conoscere (soprattutto per non perderci quando andiamo a leggere documentazione a riguardo). Il JoinPoint è un particolare punto del nostro codice dove possiamo inserire in maniera trasversale un aspetto.

Advice invece mappa la logica relativa all’aspetto: se stiamo parlando di un aspetto relativo al logging, nel rispettivo Advice troveremo la logica che permette di fare il logging. Infine abbiamo il Pointcut, che è il modo in cui applichiamo un determinato Advice ai nostri componenti.

 

Le nostre classi

Definiamo prima di tutto l’interfaccia sulla quale andremo ad operare, LibreriaInterface

Questa è un’interfaccia che utilizzeremo per creare un proxy alle chiamate tramite Spring. La classe che implementa questa interfaccia, Libreria riporta semplicemente l’implementazione dei vari metodi

L’ultima cosa che dobbiamo definire è semplicemente il mapping del concetto di libro, che verrà gestito nel ArrayList presente nella classe Libreria

Questo è il dominio della nostra applicazione, ora passiamo alla definizione dei diversi aspetti e delle relative configurazioni/classi

 

Definizioni degli Advise

In Spring abbiamo la possibilità di utilizzare diversi tipi di Advise. Quelli che riportiamo qui di seguito lavorano direttamente sui metodi, permettendoci di inserire degli aspetti relativamente a dei metodi che vengono chiamati

  • org.springframework.aop.MethodBeforeAdvice: Questo advice ci permette di intercettare la chiamata prima che venga eseguita, in modo tale da inserire un aspetto in questo istante
  • org.springframework.aop.AfterReturningAdvice: Da utilizzare per inserire un aspetto quando un determinato metodo termina la sua esecuzione
  • org.springframework.aop.ThrowsAdvice: Può essere utile per intercettare il momento in cui vengono sollevate eccezioni
  • org.springframework.intercept.MethodInterceptor: Questo advice è molto interessante perchè ci permette di gestire sia quello che succede prima e dopo di un metodo, sia di cambiare il tipo di ritorno

 

Nel nostro codice vogliamo prima di tutto inserire un aspetto che riguarda il logging, quindi definiremo una classe che implementa MethodBeforeAdvice

Con questa classe potremo loggare le informazioni relative allo stack di chiamata nel nostro codice. Ora vogliamo anche gestire gli errori su alcuni tipi di metodi (che vedremo nel seguente paragrafo di configurazione), quindi definiamo una classe che implementa ThrowsAdvice.Questa interfaccia è vuota, perchè ci permette di definire N diversi metodi per gestire N diversi tipi di errore. In questo caso avremo una definizione globale a livello di Exception

Infine definiamo un Advice che ci permette di caricare i libri all’interno della nostra classe Libreria, successivamente poi definiremo l’aspetto che intercetta le chiamate al metodo elencaLibri di questa interfaccia. In questo modo sleghiamo il nostro codice dal caricamento dei libri e quindi possiamo lavorare tranquillamente con i libri, senza preoccuparci dell’aspetto relativo al caricamento

 

Configurazione di Spring AOP

La configurazione che viene ora riportata è quella che possiamo fare all’interno di un classico file di Spring. Essendoci diverse cose da chiarire, prima vediamo il file per intero e poi scendiamo nel dettaglio

La prima cosa che viene fatta è la definizione del bean Libreria, con il riferimento all’attributo lista. Successivamente definiamo il proxy attraverso il quale utilizzeremo questo bean. La classe proxy è definita proprio all’interno di Spring, org.springframework.aop.framework.ProxyFactoryBean, e ci permette di caricare il bean ed di collegare ad esso gli aspetti.

Nella definizione del proxy indichiamo il bean a cui facciamo riferimento, Libreria, l’interfaccia LibreriaInterfaccia e gli Advisor da collegare a questo. L’Advisor, riguardando il diagramma iniziale, è l’unione tra Advice e Pointcut. Successivamente infatti vengono definiti tutti gli Advisor e per ognuno prima si definisce l’Advice che gestirà l’aspetto (le varie classi *Advice che abbiamo definito precedentemente) e un pattern che ci permette di definire a quali metodi applicare l’Advice.

In questo caso abbiamo utilizzato org.springframework.aop.support.RegexpMethodPointcutAdvisor che ci permette di definire un espressione regolare per identificare i metodi a cui applicare i nostri aspetti. Ad esempio nel caso del logging abbiamo utilizzato la regex .* che praticamente identifica ogni metodo. Questo non è l’unico modo di definire dei pointcut, per gli altri metodi vi rimando alla documentazione ufficiale di Spring AOP

 

Il test

Arrivati alla fine di questo articolo vogliamo giustamente vedere quale è il risultato quando andiamo ad utilizzare Spring AOP con questa configurazione. Vediamo quindi la classe di test che ci permette di analizzare quanto fatto

Prima di tutto dobbiamo caricare il file di configurazione di Spring che abbiamo definito precedentemente. Grazie a questo file possiamo ottenere il bean proxy. Con gli aspetti che abbiamo definiti ora avremo il logging su tutti metodi che andiamo a richiamare, avremo l’inizializzazione della variabile ArrayList quando dovremo elencare i libri e infine gestiremo il metodoDaMonitorare comunicando l’errore avvenuto. Avviando la classe avremo il seguente output

 

Conclusione

Abbiamo analizzato uno dei tanti modi che offre Spring per definire degli aspetti nel nostro codice tramite Spring AOP. Gli aspetti che abbiamo definito possono non essere molto significativi e chiaramente questa tecnica dovrebbe poi essere calata di volta in volta nella logica di business del nostro applicativo

 

Riferimenti

Documentazione ufficiale Spring AOP
Implement crosscutting concerns using Spring 2.0 AOP
The AOP@Work series
Spring in Action, Second Edition

Lascia un commento

Il tuo indirizzo email non sarà pubblicato. I campi obbligatori sono contrassegnati *