What is AOP?

Like to share

1. Overview

In this article, we will explain the AOP and its use

2. AOP

One of the key components of Spring is the AOP framework.

Aspect-Oriented programming complements Object-Oriented Programming (OOP) by providing another way of thinking about program structure. The key unit of modularity in OOP is the class, whereas in AOP the unit of modularity is the aspect. Below are some of the crosscutting concerns.

  1. Logging
  2. Caching
  3. Error handling
  4. Performance Monitoring
  5. Business rules and so on

2.1. Performance logger use case for AOP.

Consider your team created a Spring project recently and released it to production. You started getting performance alerts, and you had to find out which of your APIs are taking long to respond. So what could be possible approaches? First, you would want to log the performance of each method.

So you had to change every method and add your code to calculate the performance as below. It is a tedious and error-prone process. Isn’t it?

package com.tedblob.service;One of the key components of Spring is the AOP framework. 
import com.tedblob.model.Currency;
import com.tedblob.repository.CurrencyRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
@Service
public class CurrencyService implements ICurrencyService {
    @Autowired
    private CurrencyRepository repository;
    @Override
    public List<Currency> findAll() {
        long startTime = System.currentTimeMillis();
        try {
            return (List<Currency>) repository.findAll();
        } finally {
            long finishTime = System.currentTimeMillis();
            Duration duration = Duration.ofMillis(finishTime - startTime);
            String methodName = new Object() {}
               .getClass()
               .getEnclosingMethod()
               .getName();
            logger.info(String.format("Duration of %s execution was %s", methodName, duration));
        }
    }
    @Override
    public int count() {
        long startTime = System.currentTimeMillis();
        try {
            return repository.getCount();
        } finally {
            long finishTime = System.currentTimeMillis();
            Duration duration = Duration.ofMillis(finishTime - startTime);
            String methodName = new Object() {}
               .getClass()
               .getEnclosingMethod()
               .getName();
            logger.info(String.format("Duration of %s execution was %s", methodName, duration));
        }
    }
}

The promising alternative to this implementation is using AOP, you can separate out these crosscutting concerns from the actual code and modularise. You had to create an Aspect class as below with code for these crosscutting concerns and decide when to run - before or after or around the target method execution.

Just like a class in OOP, Aspect is the unit of modularity in AOP.

While the Spring does not depend on AOP so you can skip it if you don’t want to use it. As you have seen, AOP together with Spring IOC can provide a very capable solution.

package com.tedblob.aop.aspects;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.stereotype.Component;
import java.time.Duration;
import java.util.logging.Logger;
@Aspect
@Component
public class PerformanceLoggerAspect {
    private Logger logger = Logger.getLogger("performance.logger");
    @Around("execution(* com.tedblob.service.*(..))")
    public Object logPerformance(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
        long startTime = System.currentTimeMillis();
        try {
            return proceedingJoinPoint.proceed();
        } finally {
            long finishTime = System.currentTimeMillis();
            Duration duration = Duration.ofMillis(finishTime - startTime);
            logger.info(String.format("Duration of %s execution was %s", proceedingJoinPoint.getSignature(), duration));
        }
    }
}

The AOP will allow you to write the code only once and for all. You can also filter the target methods for which you want to execute this code. In this example, we are using @Around advice which is powerful advice that runs around the target method execution.

2.2. Key terminologies of Aspect

Let’s see few key terminologies in AOP.

Join Point: A point during the execution of a program, such as the execution of a method or the handling of an exception. In Spring, it always represents the method execution, meaning the method for which you want to add additional code.

Advice: An Action to be taken before, after, or around a particular join point or method execution. The different advice types include “around,” “before” and “after” advice.

Pointcut in Spring AOP: A predicate that matches join points. It is a set of one or more join points (method executions) for which the Advice executes.

Pointcut expression: An expression language that helps to match the target methods to apply the advice.

3. Conclusion

In this article, we have seen what is AOP and a use case to understand its importance.

I would recommend seeing this Pointcut documentation to understand more about the advice types and how we can use pointcut to filter the target methods.

One thought on “What is AOP?

Leave a Reply

Your email address will not be published. Required fields are marked *