Wednesday, 14 February 2018

How to implement AOP in Spring using annotations ?


CONCEPTS
Aspect : Implementation of cross cutting concern. Like, Txn mgt, Logging
Joinpoints : Point during program execution. Like, Method execution, Throw of exception
Advice : Action by Aspect at a particular Joinpoint.
Pointcut : Predicate to match Joinpoints. Advice is associated with a Pointcut expression.
AOP Proxy : Object created by AOP framework to implement Aspect contract.


PACKAGE STRUCTURE FOR AOP
  • Main app : com.org.TrainingApplication
  • Aspect : Use subpackage to keep the aspects - com.org.aspect.TrainingApplication
  • Aspect : Use another subpackage to keep the beans - com.org.training.A, B, C ...

Annotations on class
  • Use @Aspect to indicate the class managing the Cross cutting concern.
  • As usual, @Component is required to manage it by Spring container.

Annotations on methods
  • Use @Pointcut using pattern expression to indicate where to apply the advice.
    • pattern indicating the packages, classes, methods and arguments.
    • Provide packages, where you do not have your Application class as well 
  • Use different Advice annotations to provide actions to be taken and map with triggering events. Each of advice maps with one or many pointcut to know where to apply the advice.
    • @Before : Runs before actual method. JoinPoint object can be used to fetch method input metadata
    • @After : Runs before actual method. ProceedingJoinPoint object can be used to fetch output metadata
    • @Around : Wraps the actual method. Implementation for both (Before and After) can be provided before or after proceed() method of ProceedingJoinPoint.
    • @AfterThrowing : Runs when actual method throws exception. JoinPoint object can be used to fetch method metadata. 


@Component
@Aspect

public class Logging {
    // Pointcut for all classes & methods in package and subpackages under com.orange.training
    @Pointcut("execution(public * com.orange.training..*(..))")
    public void allMethods() {
       
    }   


     // Pointcut for all classes & methods with name starting "get" in package and subpackages under com.orange.training
     @Pointcut("execution(public * com.orange.training..*.get*(..))")
    public void restrictGetters() {
       
    }
 

    // Advice called before methods indicated in pointcuts
    @Before("allMethods() && !restrictGetters()")
    public void log() {
        System.out.println("Begining of method !!!");
    }



    // Advice called before methods indicated in pointcut
    @Before("allMethods()")
    public void log(JoinPoint jp) {
        System.out.println("Begining of method before : " + jp.getSignature());
    }
    

   
    // Advice called before and after method calls indicated in pointcut 
    // (Code before/after proceed method)
    @Around("allMethods()")
    public Object log(ProceedingJoinPoint pjp) throws Throwable {
        System.out.println("Begining of method around : " + pjp.getSignature());
        Object result = pjp.proceed();
        System.out.println(result);

        return result;
    }
    


    // Advice called after an exception is thrown in the methods indicated in pointcut        

    @AfterThrowing(pointcut="allMethods()", throwing="ex")
    public void log(JoinPoint pjp, Exception ex) {
        System.out.println("Begining of method throw : " + pjp.getSignature());
        System.out.println(ex);
    }
}


No comments:

Post a Comment

Note: only a member of this blog may post a comment.