23

Can any one tell me what is the difference between Joinpoint and Proceedingjoinpoint?

When to use Joinpoint and Proceedingjoinpoint in the method of aspect class?

I used the JoinPoint in my AspectJ class like:

@Pointcut("execution(* com.pointel.aop.test1.AopTest.beforeAspect(..))")  
public void adviceChild(){}  

@Before("adviceChild()")  
public void beforeAdvicing(JoinPoint joinPoint /*,ProceedingJoinPoint pjp - used refer book marks of AOP*/){ 

    //Used to get the parameters of the method !
    Object[] arguments = joinPoint.getArgs();
    for (Object object : arguments) {
        System.out.println("List of parameters : " + object);
    }

    System.out.println("Method name : " + joinPoint.getSignature().getName());
    log.info("beforeAdvicing...........****************...........");
    log.info("Method name : " + joinPoint.getSignature().getName());
    System.out.println("************************"); 
}

But what I see in other resources is:

@Around("execution(* com.mumz.test.spring.aop.BookShelf.addBook(..))")
public void aroundAddAdvice(ProceedingJoinPoint pjp){
    Object[] arguments = pjp.getArgs();
    for (Object object : arguments) {
        System.out.println("Book being added is : " + object);
    }
    try {
        pjp.proceed();
    } catch (Throwable e) {
        e.printStackTrace();
    }
} 

Here what will ProceedingJoinPoint do differently compare to 'JointPoint? Also what willpjp.proceed()` do for us?

Jason Law
  • 965
  • 1
  • 9
  • 21
Human Being
  • 8,269
  • 28
  • 93
  • 136

4 Answers4

33

An around advice is a special advice that can control when and if a method (or other join point) is executed. This is true for around advices only, so they require an argument of type ProceedingJoinPoint, whereas other advices just use a plain JoinPoint. A sample use case is to cache return values:

private SomeCache cache;

@Around("some.signature.pattern.*(*)")
public Object cacheMethodReturn(ProceedingJoinPoint pjp){
    Object cached = cache.get(pjp.getArgs());
    if(cached != null) return cached; // method is never executed at all
    else{
        Object result = pjp.proceed();
        cache.put(pjp.getArgs(), result);
        return result;
    }
}

In this code (using a non-existent cache technology to illustrate a point) the actual method is only called if the cache doesn't return a result. This is the exact way the Spring EHCache Annotations project works, for example.

Another specialty of around advices is that they must have a return value, whereas other advice types must not have one.

Sean Patrick Floyd
  • 292,901
  • 67
  • 465
  • 588
  • Thanks for your golden answer...One more doubt. `How to get the input parameters of a method and the return value of the same method using the @Around using the ProceedingJoinPoint ?` – Human Being Apr 03 '13 at 10:18
  • 1
    See my code above: the input parameters can be retrieved through `pjp.getArgs()`, the method return value through `pjp.proceed()` – Sean Patrick Floyd Apr 03 '13 at 10:28
  • Lets click the link for chat http://chat.stackoverflow.com/rooms/27495/room-for-anand-and-sean-patrick-floyd – Human Being Apr 03 '13 at 14:21
  • @Anand I don't have the time to chat here. look at my profile and contact me though skype or fb chat – Sean Patrick Floyd Apr 03 '13 at 15:18
12
@Around("execution(* com.mumz.test.spring.aop.BookShelf.addBook(..))")

It means before calling com.mumz.test.spring.aop.BookShelf.addBook method aroundAddAdvice method is called. After System.out.println("Book being added is : " + object); operation is completed . it will call your actual method addBook(). pjp.proceed() will call addBook() method.

Sean Patrick Floyd
  • 292,901
  • 67
  • 465
  • 588
abishkar bhattarai
  • 7,371
  • 8
  • 49
  • 66
3

Use JoinPoint with following advice types:

 @Before, @After, @AfterReturning, @AfterThrowing

Use ProceedingJoinPoint with following advice type:

@Around
Ali Yeganeh
  • 905
  • 12
  • 16
0

ProceedingJoinPoint is a JoinPoint with additional features.

ProceedingJoinPoint is used with @Around advice. @Around is very powerful advice that combines the features of rest of the Advice.

ProceedingJoinPoint::proceed is basically used to execute the original method.

Consider following example:

@Around("@annotation(com.annotations.ExecutionLoggerAround)")
public void executeLogger(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
    System.out.println("Method execution starts at :: " + System.currentTimeMillis());
    proceedingJoinPoint.proceed();
    System.out.println("Method execution completes at :: " + System.currentTimeMillis());
}

@ExecutionLoggerAround
public void generateReport() {
    System.out.println("Generating XLS report !!");
}

public @interface ExecutionLogger {
}

Now when you will call generateReport, Around advice will be executed. If you skip line proceedingJoinPoint.proceed(), the actual method will not be executed. You will see only those two println in the console.

PS: To understand better you need to know how AOP works. Spring creates proxy objects either using JDK proxy or CGLIB proxy. So its actually the proxied object that executes at runtime which use our method behind the scene.

YogendraR
  • 2,144
  • 12
  • 17