Spring Core - Types of Advice
In Spring AOP, Advice is the action taken by an aspect at a particular join point. Different types of advice allow you to execute code at various stages of a method's lifecycle.
@Before
The @Before advice runs before the target method is invoked. Uses cases include pre-processing, logging, security checks, or validation before the target method.
@Before("execution(* com.example.service.*.*(..))")
public void beforeAdvice() {
System.out.println("Executing before the target method.");
}
@After
The @After advice runs after the target method finishes, whether it completes normally or throws an exception. It's being used to perform cleanup tasks, such as closing resources or releasing locks.
@After("execution(* com.example.service.*.*(..))")
public void afterAdvice() {
System.out.println("Executing after the target method.");
}
@Around
The @Around advice is the most powerful advice. It surrounds the target method, allowing you to control the execution flow (e.g., modifying input/output, handling exceptions), because of that it can be used for fine-grained control, such as measuring method execution time, enforcing security, or modifying behavior.
@Around("execution(* com.example.service.*.*(..))")
public Object aroundAdvice(ProceedingJoinPoint joinPoint) throws Throwable {
System.out.println("Before method execution.");
Object result = joinPoint.proceed(); // Proceed with the target method
System.out.println("After method execution.");
return result;
}
@AfterReturning
The @AfterReturning advice runs after the target method completes successfully. It can be used for logging the return value, post-processing the result, or updating state after successful execution.
@AfterReturning(pointcut = "execution(* com.example.service.*.*(..))", returning = "result")
public void afterReturningAdvice(Object result) {
System.out.println("Method returned: " + result);
}
@AfterThrowing
The @AfterThrowing advice runs after the target method throws an exception. It can be used to handle or log exceptions, trigger compensating actions, or alert administrators.
@AfterThrowing(pointcut = "execution(* com.example.service.*.*(..))", throwing = "exception")
public void afterThrowingAdvice(Exception exception) {
System.out.println("An exception occurred: " + exception.getMessage());
}
Choosing the Right Advice
Advice Type | When to use |
@Before | For pre-processing tasks like logging, validation, or setting up prerequisites. |
@After | To log return values, perform post-processing, or trigger dependent actions upon success. |
@Around | For exception handling, logging errors, or compensating actions after a failure. |
@AfterReturning | To clean up resources or perform tasks that must run regardless of method outcome. |
@AfterThrowing | When you need full control over method execution, such as modifying inputs/outputs or timing. |
In an example scenario like a banking application they could be used like this:
- @Before: Validate user authentication before proceeding with a fund transfer.
- @After: Close database connections or release locks regardless of success or failure.
- @Around: Measure the time taken for the transaction or add custom logic for specific cases.
- @AfterReturning: Log the transaction details after the transfer succeeds.
- @AfterThrowing: Notify the user or log an error if the transaction fails.
