πΉ 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