Skip to main content

🧩Understanding on AOP in Spring Boot

🌟 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 TypeWhen it Runs
@BeforeBefore method execution
@AfterAfter method execution (regardless of outcome)
@AfterReturningAfter method successfully returns
@AfterThrowingAfter method throws exception
@AroundWraps 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

ScenarioNeed @Configuration?
Spring Boot (starter-aop)No, just @Aspect + @Component
Plain SpringYes, 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

Popular posts from this blog

πŸ” Is final Really Final in Java? The Truth May Surprise You 😲

πŸ’¬ “When I was exploring what to do and what not to do in Java, one small keyword caught my eye — final . I thought it meant: locked, sealed, frozen — like my fridge when I forget to defrost it.”   But guess what? Java has its own meaning of final… and it’s not always what you expect! πŸ˜… Let’s break it down together — with code, questions, confusion, jokes, and everything in between. 🎯 The Confusing Case: You Said It's Final... Then It Changed?! 🫠 final List<String> names = new ArrayList <>(); names.add( "Anand" ); names.add( "Rahul" ); System.out.println(names); // [Anand, Rahul] 🀯 Hold on... that’s final , right?! So how on earth is it still changing ? Time to dive deeper... 🧠 Why Is It Designed Like This? Here’s the key secret: In Java, final applies to the reference , not the object it points to . Let’s decode this like a spy mission πŸ•΅️‍♂️: Imagine This: final List<String> names = new ArrayList <>(); Be...

🌟 My Journey – From Zero to Senior Java Tech Lead 🌟

 There’s one thing I truly believe… If I can become a Java developer, then anyone in the world can. πŸ’― Sounds crazy? Let me take you back. πŸ•“ Back in 2015… I had zero coding knowledge . Not just that — I had no interest in coding either. But life has its own plans. In 2016, I got a chance to move to Bangalore and joined a Java course at a training center. That’s where it all started — Every day, every session made me feel like: "Ohhh! Even I can be a developer!" That course didn’t just teach Java — it gave me confidence . πŸ§ͺ Two Life-Changing Incidents 1️⃣ The Interview That Wasn't Planned Halfway through my course, I had to urgently travel to Chennai to donate blood to a family member. After that emotional rollercoaster, I found myself reflecting on my skills and the future. The next day, as I was preparing for my move to Bangalore to complete the remaining four months of my course, I randomly thought — "Let me test my skills... let me just see...

🎒 Java Loops: Fun, Fear, and ForEach() Fails

πŸŒ€ Oops, I Looped It Again! — The Ultimate Java Loop Guide You Won't Forget “I remember this question from one of my early interviews — I was just 2 years into Java and the interviewer asked, ‘Which loop do you prefer and why?’” At first, I thought, “Duh! for-each is cleaner.” But then he grilled me with cases where it fails. 😡 That led me to explore all loop types, their powers, and their pitfalls. Let’s deep-dive into every major Java loop with examples &  real-world guidance so you'll never forget again. πŸ” Loop Type #1: Classic For Loop — “The Old Reliable” ✅ When to Use: You need an index You want to iterate in reverse You want full control over loop mechanics ✅ Good Example: List<String> names = List.of("A", "B", "C"); for (int i = 0; i < names.size(); i++) { System.out.println(i + ": " + names.get(i)); } πŸ”₯ Reverse + Removal Example: List<String> item...