Spring AOP @Around advice with Examples

Hands on Guide to Spring AOP @Around advice with examples in Spring as well as Spring Boot.

What is Spring AOP Around Advice?

Spring AOP supports various types of advices and the around advice is one of those. This advice surrounds the target execution. That means, on a target method execution, the advice runs and calls the target method. Because of this, the advice gets full control over applying additional code before and after method execution.

The Around advice is very popular because of its flexibility. However, Spring recommends that, we should use the advice type which is the most specific for the requirement.

Setup Spring AOP

In this section, we will cover the initial setup part. Let’s begin by adding dependency.

Dependency

To use Spring AOP we need to add a dependency of spring-aspects project.

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-aspects</artifactId>
    <version>{spring.aop.version}</version>
</dependency>Code language: HTML, XML (xml)

Always, make sure to use the latest version or the lates possible version.

Enable Spring AOP

Once the dependency is added we need to enable Spring AOP proxies. To do that use @EnableAspectJAutoProxy annotation on the application configuration class.

This step is required for a Spring Application. However for a Spring Boot application, we can skip this step as Spring Boot automatically enables the proxies, when it discovers the library on the class path.

@Configuration
@EnableAspectJAutoProxy
public class ApplicationConfig {
    ...Code language: Java (java)

Target Class

Let’s create a target class with a method that takes a String argument and returns a List of strings.

@Slf4j
@Service
public class FileSystemStorageService {

    public List<String> readFile(String name) {
        log.info("Reading file: {}", name);
        //
        return List.of("Text from file");
    }
}Code language: Java (java)

Spring AOP @Around Advice

Now it is time to write an Around advice. To do that, we will create an Aspect class and add a method in it.

Example of Spring AOP @Around advice

@Slf4j
@Aspect
@Component
public class LoggingAspect {
    @Around("execution(* com.amitph.spring.aop.service.FileSystemStorageService.readFile(..)) ")
    public Object logBeforeAndAfterMethod(ProceedingJoinPoint joinPoint) throws Throwable {
        String targetClass = joinPoint.getTarget().getClass().getSimpleName();
        String targetMethod = joinPoint.getSignature().getName();
        String arg = joinPoint.getArgs()[0].toString();

        log.info("Executing {}.{} with argument: {}", targetClass, targetMethod, arg);

        List<String> response = (List<String>) joinPoint.proceed();

        log.info("Method returned: {}", response);
      
        return response;
    }
}Code language: Java (java)

The advice receives an argument of type ProceedingJoinPoint, which is used to execute the target method. The proceed method executes the target method with original arguments and returns the response.

Note that, the advice method has a return type of Object, which is used to return the target methods response.

Now, we will invoke the target method from another class.

Invoke target method

@Autowired
FileSystemStorageService service;

@PostConstruct
public void processFile() {
    service.readFile("test.txt");
}Code language: Java (java)

Output

INFO  | [main] c.a.s.a.s.LoggingAspect:21 - Executing FileSystemStorageService.readFile with argument: test.txt
INFO  | [main] c.a.s.a.s.FileSystemStorageService:13 - Reading file: test.txt
INFO  | [main] c.a.s.a.s.LoggingAspect:25 - Method returned: [Text from file]Code language: plaintext (plaintext)

The log lines indicates that the around advice worked correctly.

Modify Arguments and Response of Target Method

As stated above the around advice is really powerful type of advice. It can also manipulate the argument values as well as response of a target method.

Example of Around Advice manipulating argument and response

@Around("execution(* com.amitph.spring.aop.service.FileSystemStorageService.readFile(..)) ")
public Object logBeforeAndAfterMethod(ProceedingJoinPoint joinPoint) throws Throwable {

    String arg = joinPoint.getArgs()[0].toString();
    log.info("Original Argument: {}", arg);

    List<String> response =
            (List<String>) joinPoint.proceed(new Object[]{"test.xls"});

    log.info("Actual response: {}", response);
    return List.of("Alternate Response");
}Code language: Java (java)

Output:

INFO  | [main] c.a.s.a.s.LoggingAspect:19 - Original Argument: test.txt
INFO  | [main] c.a.s.a.s.FileSystemStorageService:13 - Reading file: test.xls
INFO  | [main] c.a.s.a.s.LoggingAspect:24 - Actual response: [Text from file]Code language: plaintext (plaintext)

The output shows the Around advice changed the argument value of the method, as well as changed the actual response.

Summary

This tutorial provided introduction to Spring AOP Around Advice, which is the most powerful advice. Around advice can prevent the actual method execution and return a response on methods behalf. It can also change the argument values to the target method.

For more on Spring and Spring Boot, please visit: Spring Tutorials