π My Understanding on AOP in Spring Boot
AOP = Aspect-Oriented Programming π§©
AOP is like OOP concepts but works on an Aspect model. It was developed for handling common logic like security π, logging π, transactions π°, caching π️, scheduling ⏰, and metrics π. These are called cross-cutting concerns.
π Core Terms
- Aspect: A module containing cross-cutting logic (@Aspect class).
- Join Point: A point during execution of a program, e.g., method call.
- Pointcut: Expression that defines where the aspect applies.
- Advice: Action taken at a join point, e.g., logging before a method.
- Proxy: Wrapper around the actual object that intercepts calls.
π Types of Advice
Advice Type | When it Runs |
---|---|
@Before | Before method execution |
@After | After method execution (regardless of outcome) |
@AfterReturning | After method successfully returns |
@AfterThrowing | After method throws exception |
@Around | Wraps method execution (before + after) |
⚙ How AOP Works Internally in Spring Boot
Spring uses proxies to implement AOP. When a method is called on a bean, the proxy intercepts it and applies the advice.
Proxy Types
- JDK Dynamic Proxy: Used if target class implements an interface. Proxy only implements the interface.
- CGLIB Proxy: Used if the class doesn’t implement an interface. Subclass of target class is created at runtime.
Why two types? π§ Because Spring wants to maximize compatibility:
- Interfaces → JDK proxy
- Concrete class without interface → CGLIB proxy
π» Example: Logging Aspect in Spring Boot
@Aspect
@Component
public class LoggingAspect {
@Before("execution(* com.example.service.*.*(..))")
public void logBefore(JoinPoint joinPoint) {
System.out.println("Before method: " + joinPoint.getSignature().getName());
}
@After("execution(* com.example.service.*.*(..))")
public void logAfter(JoinPoint joinPoint) {
System.out.println("After method: " + joinPoint.getSignature().getName());
}
}
π Enabling AOP in Spring Boot
Spring Boot auto-configures AOP if spring-boot-starter-aop
is present. You don’t need @EnableAspectJAutoProxy
explicitly.
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-aop</artifactId> </dependency>
❓ Q&A: What happens if you don’t add this dependency?
Question: What happens if we don’t add spring-boot-starter-aop
?
Answer: ❌
- AOP aspects defined with
@Aspect
won’t be applied. - Annotations like
@Transactional
,@Cacheable
, and@Scheduled
may not work properly because Spring cannot create proxies to handle their behavior. - Basically, all cross-cutting concerns depending on AOP will fail silently or behave unexpectedly.
π‘ Cross-Cutting Annotations Using AOP
1️⃣ Transaction Management
@Service
public class PaymentService {
@Transactional
public void processPayment() {
// DB operations
}
}
2️⃣ Caching
@Service
public class ProductService {
@Cacheable("products")
public Product getProduct(Long id) {
// expensive DB call
}
}
3️⃣ Scheduling
@Component
public class TaskScheduler {
@Scheduled(fixedRate = 5000)
public void runTask() {
System.out.println("Task executed at: " + LocalDateTime.now());
}
}
π‘ Important Unknown Points
- Self-invocation: Calling a method internally in the same bean bypasses proxy. Advice won’t run.
- Spring-managed beans: Advice only works on beans managed by Spring.
- Some annotations use AOP internally: @Transactional, @Cacheable, @Scheduled.
- Performance: Proxies add very small overhead. CGLIB slightly heavier than JDK proxy.
π Flow Diagram: How AOP Works (Aspect, JoinPoint, Pointcut, Advice)
Visual representation of Spring Boot AOP flow:
[Controller] ---> calls ---> [Proxy of Service] / \ Before Advice (@Before) After Advice (@After) \ / ---> [Actual Service Method] ^ | JoinPoint: Method execution point | Pointcut: Expression selecting join points | Aspect: Class containing advice logic
✅ Calling Before & After in Spring Boot
- No separate
@Configuration
class is required in Spring Boot. Just@Aspect
+@Component
. - Separate configuration is needed only in plain Spring to enable
@EnableAspectJAutoProxy
or customize proxy behavior. - Spring Boot auto-scans aspects via
@SpringBootApplication
component scanning.
π Summary Table
Scenario | Need @Configuration? |
---|---|
Spring Boot (starter-aop) | No, just @Aspect + @Component |
Plain Spring | Yes, to enable @EnableAspectJAutoProxy |
Custom proxy behavior (force CGLIB) | Yes, configure in @Configuration |
π― Key Takeaways
- Use
@Aspect
for cross-cutting concerns. - Advice types: Before, After, AfterReturning, AfterThrowing, Around.
- Proxy types: JDK (interface), CGLIB (class) and know why they differ.
- Some Spring annotations internally use AOP (transactions, cache, scheduling).
- Self-invocation bypasses proxy.
- Dependency
spring-boot-starter-aop
is required for AOP to work correctly.
π Wrapping Up
Spring Boot AOP is like magic ✨—you just write your @Aspect
and Spring handles the proxy behind the scenes. Understanding the flow of how proxies intercept calls, and knowing the difference between JDK and CGLIB proxies, is key to mastering Spring cross-cutting concerns.
Next time you want logging, caching, transaction handling, or scheduling without cluttering your business logic, remember: just write an aspect or use the built-in annotations and let Spring do the heavy lifting! πͺ
Have you tried writing a custom aspect or using caching/transaction annotations in your project? Share your experiences below! π
Comments
Post a Comment