@
L'AOP consiste à injecter du code avant, après ou autour des appels à certaines méthodes.
L'AOP est utilisé pour gérer des aspects transversaux de l'application: logging, caching, timing ...
Plusieurs frameworks permettent de faire de l'AOP: Spring AOP, AspectJ, ...
En Spring, cette injection de code se fait à runtime et uniquement sur des objets gérés par le conteneur IoC.
AspectJ réalise cette injection (aussi appelé tissage) au moment de la compilation. On peut configurer Spring réaliser le tissage en utilisant AspectJ mais nous allons utiliser Spring AOP ici.
Spring crée à l'exécution un proxy pour le bean dans lequel on veut injecter le code.
Le code à injecter est fourni dans des classes marquées par l'annotation @Aspect.
A la création du bean, un proxy est crée automatiquement. Ce proxy se charge d'appeler les les aspects concernant cette méthode.
Comme les proxys sont fait dynamiquement, on a les limitations vu dans le cours de design patterns.
@Aspect
@Component
public class MyAspect {
@Before("execution(* fr.uge.jee.aop.Database.add*(..))")
public void beforeAdd(JoinPoint jp) throws Throwable {
System.out.println("This is printed before the method call")
}
}
Le code de beforeAdd sera injecté avant l'appel à toute méthode d'un bean de type fr.uge.jee.aop.Database dont le nom commence par add.
L'objet JoinPoint représente le point d'injection. C'est à dire la méthode où le code va être injecter.
@Aspect
@Component
public class MyAspect {
@AfterReturning(value="execution(* fr.uge.jee.aop.Database.add*(..))",returning="returnValue")
public void afterAdd(JoinPoint jp,Object returnValue) throws Throwable {
System.out.println("This is printed after the method call with returned "+returnValue);
}
}
On a accès à la valeur de retour de la méthode avec value.
@Aspect
@Component
public class MyAspect {
@Around(value="execution(* fr.uge.jee.aop.Database.add*(..))")
public Object around(ProceedingJoinPoint pjp) throws Throwable {
System.out.println("This is printed before the method");
var ret = pjp.proceed(); // call the method
System.out.println("This is printed after the method");
return ret;
}
}
Le ProceedingJoinPoint représente l'appel qui va se faire à la méthode.
@Configuration
@ComponentScan
@EnableAspectJAutoProxy
public class Config {
}