What Is A Spring Aspect? π²
Simply put, it's a reusable part of code (Advice) that is injected into a certain part (joinPoint) of the application (defined by Pointcuts) at runtime.
Why Use it? π€¨
Address common concerns across our application.
Like what?
Logging π
Transaction management π
Caching π
Security π
It's used all over the place in Spring framework
- Aspect Oriented Programming (AOP) is one of the two core concepts that the Spring framework is built on, the second one being Dependency Injection.
Let's Get To Know the agents behind Spring Aspects π₯·π½
Join point π§
A joinpoint is a candidate point in the Program Execution of the application where an aspect can be plugged in.
This point could be a method being called, an exception being thrown, or even a field being modified.
These are the points where your aspectβs code can be inserted into the normal flow of your application to add new behavior.
Advice π
- The code that addresses system wide concerns (logging, security checks, etc...) representing the action to perform at a joinpoint specified by a pointcut.
Pointcut π
- A pointcut is an expression that defines at what joinpoints, the associated Advice should be applied.
Aspect π
- Aspect is the class that defines the aspectβs behavior and a pointcut defining where the aspect should be executed.
Ready For Some Coding? π€©
Let's write a simple use-case of logging something to the console on the call of a certain method.
We'll start by adding the maven dependency for AOP
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
Then, let's create a class and annotate it with @Aspect
to mark that this class will contain Advice methods and Pointcuts.
We also need to annotate it with @Component
so it becomes managed by Spring.
This class will handle the simple task of logging to the console.
@Component
@Aspect
public class LoggingAspect {
@Pointcut("@annotation(Loggable)")
public void logAllMethodCallsPointcut(){
}
@Before("logAllMethodCallsPointcut()")
public void logAllMethodCallsAdvice(){
System.out.println("From Aspect");
}
}
We need to create the loggable annotation
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Loggable {
}
What did we just write? π
-
@Pointcut("@annotation(Loggable)")
declares thelogAllMethodCallsPointcut
method as a pointcut for all method annotated withLoggable
. -
@Before("logAllMethodCallsPointcut()")
declareslogAllMethodCallsAdvice
advice which will be called before any method annotated withLoggable
.
Now let's create a service that will act as our join point π§
@Service
public class HomeService {
@Loggable
// this here is what's called a join point
public void homePage(){
System.out.println("From Service");
}
}
Now when we call the homePage
method, the logAllMethodCallsAdvice
advice method will be called before it.
So we will see the following logs π
From Aspect
From Service
Remind Me Why Are We doing This? π’
This example seems useless for the simple case we have, however imagine having a system with hundreds of methods that you want to log something about them.
- Would you call the same code before each and everyone? π€
- What happens if you want to change the implementation of the logging process?
- You need to search for all the usages and change them π
- Or, you can create a service and call it from all those places, but imagine having more things other than logging.
- You need to create and call separate service for everyone π€
Aspects are a life saver as you can now see. ππ
Conclusion π
- Aspects is one of the most important concepts of the Spring framework.
- It's quite handy and provides a mean for clean reusable code.
- It has a wide range of use-cases (We only discuss logging).
Top comments (0)