Exemple Spring AOP - Conseils
Spring AOP + AspectJ
L'utilisation d'AspectJ est plus flexible et plus puissante, veuillez vous référer à ce tutoriel -Using AspectJ annotation in Spring AOP.
Le cadre Spring AOP (Aspect-oriented programming) est utilisé pour modulariser les préoccupations transversales dans certains aspects. En termes simples, il s'agit simplement d'un intercepteur pour intercepter certains processus, par exemple, lorsqu'une méthode est exécutée, Spring AOP peut détourner la méthode d'exécution et ajouter des fonctionnalités supplémentaires avant ou après l'exécution de la méthode.
Dans Spring AOP, 4 types de conseils sont pris en charge:
-
Avant conseil - Exécuter avant l'exécution de la méthode
-
Après avoir renvoyé un conseil - Exécuté après que la méthode a renvoyé un résultat
-
After throwing advice - Exécuté après que la méthode lève une exception
-
Autour des conseils - Exécutez l'exécution de la méthode, combinez les trois conseils ci-dessus.
L'exemple suivant vous montre comment fonctionnent les conseils Spring AOP.
Exemple simple de printemps
Créez une classe de service client simple avec quelques méthodes d'impression pour une démonstration ultérieure.
package com.example.customer.services; public class CustomerService { private String name; private String url; public void setName(String name) { this.name = name; } public void setUrl(String url) { this.url = url; } public void printName() { System.out.println("Customer name : " + this.name); } public void printURL() { System.out.println("Customer website : " + this.url); } public void printThrowException() { throw new IllegalArgumentException(); } }
Fichier: Spring-Customer.xml - Un fichier de configuration de bean
Exécuter
package com.example.common; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; import com.example.customer.services.CustomerService; public class App { public static void main(String[] args) { ApplicationContext appContext = new ClassPathXmlApplicationContext( new String[] { "Spring-Customer.xml" }); CustomerService cust = (CustomerService) appContext.getBean("customerService"); System.out.println("*************************"); cust.printName(); System.out.println("*************************"); cust.printURL(); System.out.println("*************************"); try { cust.printThrowException(); } catch (Exception e) { } } }
Sortie
************************* Customer name : Yong Mook Kim ************************* Customer website : http://www.example.com *************************
Un simple projet Spring pour DI un bean et sortir quelques Strings.
Conseils du printemps AOP
Maintenant, joignez les conseils Spring AOP au service client ci-dessus.
1. Avant conseil
Il s'exécutera avant l'exécution de la méthode. Créez une classe qui implémente l'interface MethodBeforeAdvice.
package com.example.aop; import java.lang.reflect.Method; import org.springframework.aop.MethodBeforeAdvice; public class HijackBeforeMethod implements MethodBeforeAdvice { @Override public void before(Method method, Object[] args, Object target) throws Throwable { System.out.println("HijackBeforeMethod : Before method hijacked!"); } }
Dans le fichier de configuration du bean (Spring-Customer.xml), créez un bean pour la classeHijackBeforeMethod et un nouvel objet proxy nommé «customerServiceProxy».
-
‘Target’ - Définissez le bean que vous souhaitez détourner.
-
‘InterceptorNames’ - Définissez la classe (conseil) que vous souhaitez appliquer sur cet objet proxy / cible.
hijackBeforeMethodBean
Note
Pour utiliser le proxy Spring, vous devez ajouter la bibliothèque CGLIB2. Ajoutez ci-dessous dans le fichier Maven pom.xml.
cglib cglib 2.2.2
Exécutez-le à nouveau, maintenant vous obtenez le nouveau beancustomerServiceProxyau lieu du beancustomerService d'origine.
package com.example.common; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; import com.example.customer.services.CustomerService; public class App { public static void main(String[] args) { ApplicationContext appContext = new ClassPathXmlApplicationContext( new String[] { "Spring-Customer.xml" }); CustomerService cust = (CustomerService) appContext.getBean("customerServiceProxy"); System.out.println("*************************"); cust.printName(); System.out.println("*************************"); cust.printURL(); System.out.println("*************************"); try { cust.printThrowException(); } catch (Exception e) { } } }
Sortie
************************* HijackBeforeMethod : Before method hijacked! Customer name : Yong Mook Kim ************************* HijackBeforeMethod : Before method hijacked! Customer website : http://www.example.com ************************* HijackBeforeMethod : Before method hijacked!
Il exécutera la méthodeHijackBeforeMethod’s before(), avant que les méthodes de chaque service client ne soient exécutées.
2. Après avoir renvoyé des conseils
Il s'exécutera une fois que la méthode aura renvoyé un résultat. Créez une classe qui implémente l'interfaceAfterReturningAdvice.
package com.example.aop; import java.lang.reflect.Method; import org.springframework.aop.AfterReturningAdvice; public class HijackAfterMethod implements AfterReturningAdvice { @Override public void afterReturning(Object returnValue, Method method, Object[] args, Object target) throws Throwable { System.out.println("HijackAfterMethod : After method hijacked!"); } }
Fichier de configuration du bean
hijackAfterMethodBean
Réexécutez-le, sortie
************************* Customer name : Yong Mook Kim HijackAfterMethod : After method hijacked! ************************* Customer website : http://www.example.com HijackAfterMethod : After method hijacked! *************************
Il exécutera la méthodeHijackAfterMethod’s afterReturning(), après chaque méthode de customerService dont le résultat est renvoyé.
3. Après avoir jeté des conseils
Il s'exécutera après que la méthode lève une exception. Créez une classe qui implémente l'interface ThrowsAdvice et créez une méthodeafterThrowing pour détourner l'exception deIllegalArgumentException.
package com.example.aop; import org.springframework.aop.ThrowsAdvice; public class HijackThrowException implements ThrowsAdvice { public void afterThrowing(IllegalArgumentException e) throws Throwable { System.out.println("HijackThrowException : Throw exception hijacked!"); } }
Fichier de configuration du bean
hijackThrowExceptionBean
Exécutez-le à nouveau, sortie
************************* Customer name : Yong Mook Kim ************************* Customer website : http://www.example.com ************************* HijackThrowException : Throw exception hijacked!
Il exécutera la méthodeHijackThrowException’s afterThrowing(), si les méthodes de customerService lèvent une exception.
4. Autour des conseils
Il combine les trois conseils ci-dessus et s'exécute pendant l'exécution de la méthode. Créez une classe qui implémente l'interfaceMethodInterceptor. Vous devez appeler les“methodInvocation.proceed(); ”pour procéder à l'exécution de la méthode d'origine, sinon la méthode d'origine ne s'exécutera pas.
package com.example.aop; import java.util.Arrays; import org.aopalliance.intercept.MethodInterceptor; import org.aopalliance.intercept.MethodInvocation; public class HijackAroundMethod implements MethodInterceptor { @Override public Object invoke(MethodInvocation methodInvocation) throws Throwable { System.out.println("Method name : " + methodInvocation.getMethod().getName()); System.out.println("Method arguments : " + Arrays.toString(methodInvocation.getArguments())); // same with MethodBeforeAdvice System.out.println("HijackAroundMethod : Before method hijacked!"); try { // proceed to original method call Object result = methodInvocation.proceed(); // same with AfterReturningAdvice System.out.println("HijackAroundMethod : Before after hijacked!"); return result; } catch (IllegalArgumentException e) { // same with ThrowsAdvice System.out.println("HijackAroundMethod : Throw exception hijacked!"); throw e; } } }
Fichier de configuration du bean
hijackAroundMethodBean
Exécutez-le à nouveau, sortie
************************* Method name : printName Method arguments : [] HijackAroundMethod : Before method hijacked! Customer name : Yong Mook Kim HijackAroundMethod : Before after hijacked! ************************* Method name : printURL Method arguments : [] HijackAroundMethod : Before method hijacked! Customer website : http://www.example.com HijackAroundMethod : Before after hijacked! ************************* Method name : printThrowException Method arguments : [] HijackAroundMethod : Before method hijacked! HijackAroundMethod : Throw exception hijacked!
Il exécutera la méthodeHijackAroundMethod’s invoke(), après chaque exécution de la méthode customerService.
Conclusion
La plupart des développeurs Spring ne mettent en œuvre que le «conseil Autour», car il peut appliquer tout le type de conseil, mais une meilleure pratique devrait choisir le type de conseil le plus approprié pour répondre aux exigences.
Pointcut
Dans cet exemple, toutes les méthodes d'une classe de service client sont automatiquement interceptées (conseil). Mais dans la plupart des cas, vous devrez peut-être utiliserPointcut and Advisor pour intercepter une méthode via son nom de méthode.
Télécharger le code source
Téléchargez-le -Spring-AOP-Advice-Examples.zip (8 Ko)