@ JEE Back-End - Aspect Oriented Programming

JEE Back-end

Spring Core : Aspect Oriented Programming

Aspect Oriented Programming (AOP)

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

AOP en Spring

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.

Injection @Before une méthode

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

Injection @AfterReturning une méthode

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

Injection @Around une méthode

@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 with Aspects

@Configuration
@ComponentScan
@EnableAspectJAutoProxy
public class Config {
}