Spring AOP

πŸ”Ή What is AOP?

AOP lets you separate cross-cutting concerns (like logging, security, transactions, caching) from business logic.
In Spring Boot, AOP is usually implemented using Spring AOP with annotations like @Aspect.


πŸ”Ή Key Concepts

  • Aspect β†’ @Aspect
  • Advice β†’ @Before, @After, @AfterReturning, @AfterThrowing, @Around
  • Pointcut β†’ @Pointcut
  • Join Point β†’ (no annotation; accessible via JoinPoint parameter in advice methods)

πŸ”Ή Example: Logging with AOP

1. Add Dependency

If you’re using Maven, include Spring AOP starter:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-aop</artifactId>
</dependency>

2. Service Class (Business Logic)

package com.example.demo.service;

import org.springframework.stereotype.Service;

@Service
public class UserService {

    public String getUserById(Long id) {
        return "User with ID: " + id;
    }

    public void createUser(String name) {
        System.out.println("User " + name + " created successfully!");
    }
}

3. Aspect Class (Logging Cross-cutting Concern)

package com.example.demo.aspect;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.stereotype.Component;

@Aspect
@Component
public class LoggingAspect {

    // Before executing any method in service package
    @Before("execution(* com.example.demo.service.*.*(..))")
    public void logBefore(JoinPoint joinPoint) {
        System.out.println("➑️ Before Method: " + joinPoint.getSignature().getName());
    }

    // After returning from method execution
    @AfterReturning(
        pointcut = "execution(* com.example.demo.service.*.*(..))",
        returning = "result")
    public void logAfter(JoinPoint joinPoint, Object result) {
        System.out.println("βœ… After Method: " + joinPoint.getSignature().getName() + 
                           " | Returned: " + result);
    }
}

// Pointcut
@Pointcut("execution(* com.example.service.*.*(..))")
public void serviceMethods() {}

// Before Advice
@Before("serviceMethods()")
public void logBefore(JoinPoint joinPoint) { // Join Point
    System.out.println("Before method: " + joinPoint.getSignature().getName());
}

// After Advice
@After("serviceMethods()")
public void logAfter(JoinPoint joinPoint) { // Join Point
    System.out.println("After method: " + joinPoint.getSignature().getName());
}

5. Run and Test

When you hit:

  • GET /users/10
  • POST /users?name=Alice

Logs will print:

➑️ Before Method: getUserById
βœ… After Method: getUserById | Returned: User with ID: 10
➑️ Before Method: createUser
βœ… After Method: createUser | Returned: null

Leave a Reply