DEV Community

Cover image for Intro To Spring's Aspects
Abdulcelil Cercenazi
Abdulcelil Cercenazi

Posted on

Intro To Spring's Aspects

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

Enter fullscreen mode Exit fullscreen mode

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.

public class LoggingAspect {
    public void logAllMethodCallsPointcut(){    
    public void logAllMethodCallsAdvice(){
        System.out.println("From Aspect");
Enter fullscreen mode Exit fullscreen mode

We need to create the loggable annotation

public @interface Loggable {  
Enter fullscreen mode Exit fullscreen mode

What did we just write? ๐Ÿ‘€

  • @Pointcut("@annotation(Loggable)") declares the logAllMethodCallsPointcut method as a pointcut for all method annotated with Loggable.
  • @Before("logAllMethodCallsPointcut()") declares logAllMethodCallsAdvice advice which will be called before any method annotated with Loggable.

Now let's create a service that will act as our join point ๐Ÿง 

public class HomeService {  
  // this here is what's called a join point  
  public void homePage(){  
        System.out.println("From Service");  
Enter fullscreen mode Exit fullscreen mode

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).

For more details you can check this rich resource ๐Ÿค.

Source code on GitHub ๐Ÿ’ป.

Discussion (0)