Types of advice

In the preceding section, we learned different terminologies of AOP and how to define the pointcut expression. In this section, we will learn about the different types of advice in Spring AOP:

  • @Before: This advice is executed before the join point and it is defined in aspect using the @Before annotation. The declaration is shown in the following code:
@Pointcut("execution(* com.packt.springhighperformance.ch03.bankingapp.service.TransferService.transfer(..))")
public void transfer() {}

@Before("transfer()")
public void beforeTransfer(JoinPoint joinPoint){
LOGGGER.info("validate account balance before transferring amount");
}
If the @Before method throws an exception, the transfer target method would not get called. This is a valid use of @Before advice.
  • @After: This advice is executed after the join point (method) exits/returns either normally or with any exception. To declare this advice, use the @After annotation. The declaration is shown in the following code:
@Pointcut("execution(* com.packt.springhighperformance.ch03.bankingapp.service.TransferService.transfer(..))")
public void transfer() {}

@After("transfer()")
public void afterTransfer(JoinPoint joinPoint){
LOGGGER.info("Successfully transferred from source account to dest
account");
}
  • @AfterReturning: As we know in @After advice, the advice is executed in any case where the join point exits normally or with an exception. Now, if we want to run an advice only after a matched method returns normally, then what? Then we need @AfterReturning. Sometimes we need to perform some operation based on the value returned by the method. In those cases, we can use the @AfterReturning annotation. The declaration is shown in the following code:
@Pointcut("execution(* com.packt.springhighperformance.ch03.bankingapp.service.TransferService.transfer(..))")
public void transfer() {}


@AfterReturning(pointcut="transfer() and args(source, dest, amount)", returning="isTransferSuccessful" )
public void afterTransferReturns(JoinPoint joinPoint, Account source, Account dest, Double amount, boolean isTransferSuccessful){
if(isTransferSuccessful){
LOGGGER.info("Amount transferred successfully ");
//find remaining balance of source account
}
}
  • @AfterThrowing: This advice is called when an exception is thrown by a matched method in an expression. This is useful when we want to take some action when any particular type of exception is thrown or we want to track method execution to correct errors. It is declared using the @AfterThrowing annotation, as shown in the following code:
@Pointcut("execution(* com.packt.springhighperformance.ch03.bankingapp.service.TransferService.transfer(..))")
public void transfer() {}

@AfterThrowing(pointcut = "transfer()", throwing = "minimumAmountException")
public void exceptionFromTransfer(JoinPoint joinPoint, MinimumAmountException minimumAmountException) {
LOGGGER.info("Exception thrown from transfer method: " +
minimumAmountException.getMessage());
}

Similar to @AfterThrowing returning attribute, the throwing attribute in the @AfterThrowing advice must match the name of the parameter in the advice method. The throwing attribute restricts matching to those method executions that throws an exception of the specified type. 

  • @Around: The last and final advice that is applied around the matched method. This means that it is a combination of the @Before and @After advice we saw earlier. However, the @Around advice is more powerful than @Before and @After combined. It is powerful because it can decide whether to proceed to the join point method or return its own value or throw an exception. The @Around advice can be used with the @Around annotation. The first parameter of the advice method in @Around advice should be ProceedingJoinPoint. The following is the code sample of how to use the @Around advice:
@Pointcut("execution(* com.packt.springhighperformance.ch03.bankingapp.service.TransferService.transfer(..))")
public void transfer() {}


@Around("transfer()")
public boolean aroundTransfer(ProceedingJoinPoint proceedingJoinPoint){
LOGGER.info("Inside Around advice, before calling transfer method ");
boolean isTransferSuccessful = false;
try {
isTransferSuccessful = (Boolean)proceedingJoinPoint.proceed();
} catch (Throwable e) {
LOGGER.error(e.getMessage(), e);
}
LOGGER.info("Inside Around advice, after returning from transfer
method");
return isTransferSuccessful;
}
We can invoke proceed once, many times, or not at all within the body of the @Around advice.
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset