Spring AOP with AspectJ annotations allows developers to define aspects, pointcuts, and advice using annotations instead of XML configuration. It simplifies implementation by using annotations like @Aspect, @Before, and @Around directly in Java classes. This approach improves readability, reduces configuration complexity, and integrates seamlessly with Spring Boot applications.
- Uses annotations such as @Aspect, @Pointcut, @Before, @After, etc.
- Enables clean separation of cross-cutting concerns like logging and security.
- Eliminates the need for XML-based AOP configuration.
Some Common AspectJ Annotations
Common AspectJ annotations used to create advice are as follows:
@Pointcut
@Pointcut defines a reusable expression that selects specific join points where advice should be applied. It helps avoid repeating expressions.
- Reusable across multiple advice methods.
- Improves readability and maintainability.
// Annotation
@Before("execution(* abc.def.gettingstarted.dao.*.add(..))")
public void allMethods(Point Point)
{
// Aspect body
}
@Before(Before Advice)
@Before advice is executed before the target method is invoked. It is commonly used for tasks like logging, authentication, or validation. It does not control the execution flow of the target method.
- Runs before method execution.
- Cannot modify the return value of the method.
@Aspect
public class Logging {
@PointCut("execution(* com.gfg.Student.getName(..))")
private void selectGetName(){}
@Before("selectGetName()")
public void beforeAdvice(){
System.out.println("Going to setup student profile.");
}
}
@AfterReturning(After Returning Advice)
@After advice executes after the target method finishes, regardless of whether it completes successfully or throws an exception. It is similar to a finally block in Java.
- Executes after method completion.
- Runs for both success and exception cases.
@Slf4j
@Aspect
@Component
public class LoggingAspect {
@AfterReturning("execution(* com.gfg.spring.aop.service.FileSystemStorageService.readFile(..))")
public void methodCall(JoinPoint jp, Exception ex) {
log.error("Target method is successfully completed!!");
}
}
@AfterThrowing(After Throwing Advice)
@AfterThrowing advice is triggered when the target method throws an exception. It is mainly used for exception logging and handling.
- Executes only when an exception occurs.
- Can access exception details.
@AfterThrowing(PointCut = "execution(* com.gfg.Student.*(..))", throwing = "error")
public void throwingAdvice(JoinPoint jp, Throwable error){
System.out.println("Method Signature: " + jp.getSignature());
System.out.println("Exception: "+error);
}
@After(After/Finally Advice)
An After advice runs after the target method is finished or includes when the target method results in an exception.
- This advice is similar to the final block in Java which always executes irrespective of the outcome.
@After("execution(* com.gfg.saop.after.dao.*.*(..))")
public void logResult(JoinPoint joinPoint)
{
System.out.println(
"After advice executed: "
+ joinPoint.getSignature().toShortString());
}
@Around(Around Advice)
@Around advice surrounds the target method execution, allowing execution both before and after the method call. It provides full control over method execution.
- Runs before and after method execution.
- Can control whether the method executes or not.
@Around("execution(* com.example.service.*.*(..))")
public Object aroundAdvice(ProceedingJoinPoint pjp) throws Throwable {
System.out.println("Before method");
Object result = pjp.proceed();
System.out.println("After method");
return result;
}