When I started learning Spring, I noticed something about many of the tutorials I found.
They often showed how to use a feature, but not always why it worked or when you should choose one approach over another.
I learn best by building things and documenting what I discover, so I started a project called spring-by-example.
The idea is simple: instead of building one large application, Iβm creating a collection of small, focused examples where each example explores a specific Spring concept with clear explanations, tests, and documentation.
Iβm happy to say that Iβve now completed Module 7 β Spring AOP. π
The module covers:
- What is AOP?
- JDK Dynamic Proxies
- CGLIB Proxies
- Creating an Aspect
- Before Advice
- After Advice
- After Returning Advice
- Around Advice
- Pointcuts
- Advice Ordering
One of the most interesting parts of this module was understanding that Spring AOP is built around proxies.
Before getting into Spring's AOP abstractions, I explored JDK Dynamic Proxies and CGLIB proxies separately. That made it easier to understand what Spring is doing behind the scenes when it creates an AOP proxy around a Spring-managed bean.
For example, instead of manually creating a proxy, Spring can use an aspect such as:
@Aspect
public class LoggingAspect {
@Before("execution(* com.springbyexample.GreetingService.greet(..))")
public void beforeGreeting() {
System.out.println("Before greeting");
}
}
Spring then uses the pointcut to determine which method calls should receive that behavior.
That led into another important concept: advice.
I explored several different types of advice:
-
@Beforeβ runs before the target method. -
@Afterβ runs after the method invocation completes. -
@AfterReturningβ runs when the method returns successfully. -
@Aroundβ surrounds the target invocation and gives the advice control over when the target executes throughProceedingJoinPoint.
Around advice was particularly interesting because proceed() determines whether the target method actually gets invoked.
I also explored pointcuts, which helped clarify an important distinction:
Pointcut
β
Where should the advice apply?
Advice
β
What should happen?
For example:
@Before("execution(* com.springbyexample.GreetingService.greet(..))")
uses the pointcut to tell Spring which method should be intercepted.
Finally, I looked at advice ordering.
When multiple aspects apply to the same method, @Order can be used to control their precedence. Lower order values have higher precedence, and the ordering becomes especially interesting when looking at how @Before and @After advice execute around the target method.
One of the things I wanted to understand through these examples was not just how to write an aspect, but what is actually happening when a method call goes through Spring AOP:
Caller
β
Spring AOP Proxy
β
Pointcut matching
β
Ordered Advice
β
Target Method
β
Ordered Advice
β
Return value
That connects nicely with the earlier proxy examples and makes Spring AOP feel much less like "magic."
The goal of spring-by-example isn't just to collect Spring annotations and APIs.
I'm trying to understand how the Spring container works, how its features fit together, and why these features exist, one concept at a time.
The project is open source, and Iβm continuing to build it as I learn:
π GitHub
π GitLab
Thereβs still a long way to go, but completing another module feels like a good milestone. π
Next up: Spring Transactions β continuing the journey by exploring another important part of the Spring ecosystem.
If youβve worked with Spring AOP before, what concept do you think is the most difficult for developers to understand: proxies, pointcuts, advice, or advice ordering?
Top comments (0)