Spring AOP @AfterThrowing advice with Examples

An Introduction to Spring AOP @AfterThrowing advice. Learn How to write After throwing advice in a Spring or Spring Boot Project.

Spring AOP @AfterThrowing advice

The @AfterThrowing is a Spring AOP advice. Advices in Aspect Oriented Programming encapsulate some of the cross cutting concerns, so that the target classes can focus on the primary functionality.

As the name denotes, AfterThrowing advice executes when the target method throws an exception. It won’t run if the method finishes successfully, or the method swallows the thrown exception. Thus, the AfterThrowing advice is useful, when for an application we want to build a common exception handler that can catch a different exceptions thrown by a different target methods and takes an action.

Spring AOP Setup

Before we write our Example of AfterThrowing advice in a Spring or Spring Boot application, we will do some initial steps.

Dependency

First, we will add dependency of spring-aspects in our project.

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

Enable Spring AOP

Now, that the dependency is added, we need to enable AOP proxies in a Spring Application. To do that, we can use @EnablespectJAutoProxy on application configuration file.

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

For a Spring Boot application, you can skip this test as the auto configuration framework in Spring Boot automatically enables the proxies.

Target Class

We will create a target class with a method on which, the advice will be applied. This can be any normal Java class, we will also annotate it with @Service, so that we can inject it into another bean and invoke the target method.

Notice that, the target method throws an exception if the given file is not found.

@Slf4j
@Service
public class FileSystemStorageService {

    public List<String> readFile(String name) throws FileNotFoundException {
        log.info("Reading file: {}", name);
        InputStream is = new FileInputStream(name);
        // Skipped
        return List.of("Text from file");
    }
}Code language: Java (java)

Target Method Invoker

Next, we will create an invoker for the target method. We expect the target method should throw the exception. Thus, the invoker sends an invalid file path to the method.

@Autowired
FileSystemStorageService service;

@PostConstruct
public void processFile() throws FileNotFoundException {
    List<String> result = service.readFile("test.txt");
    System.out.println(result);
}Code language: Java (java)

Spring AOP @AfterThrowing Advice

In order to write an advice, we need to create an aspect class with the advice method in it. To make a class an Aspect we need to annotate it with @Aspect.

@Slf4j
@Aspect
@Component
public class LoggingAspect {
    @AfterThrowing("execution(* com.amitph.spring.aop.service.FileSystemStorageService.readFile(..))")
    public void logAfterThrowing() {

        log.error("Target Method resulted into exception");
        notificationService.error(ERROR_MESSAGE);
    }
}Code language: Java (java)

The advice method, is annotated with @AfterThrowing and provides a Pointcut expression to match the target method.

When we start the application, we see the advice is executed correctly.

INFO  | [main] c.a.s.a.s.FileSystemStorageService:16 - Reading file: test.txt
ERROR | [main] c.a.s.a.s.LoggingAspect:15 - Target Method resulted into exceptionCode language: plaintext (plaintext)

Get Exception Details in AfterThrowing Advice

In the previous example, we learned that the AfterThrowing advice runs when the target method results in exception. Next, we will learn how to pass the exception details as well as target method details to the the advice.

In order to provide exception details to the AfterThrowing advice, we need to add an argument of type exception as well as register the argument name in throwing clause of the Pointcut.

Next, is an example of passing Exception and JoinPoint to the AfterThrowing advice in Spring AOP.

@Slf4j
@Aspect
@Component
public class LoggingAspect {
    @AfterThrowing(value = "execution(* com.amitph.spring.aop.service.FileSystemStorageService.readFile(..))",
            throwing = "ex")
    public void logAfterThrowing(JoinPoint joinPoint, Exception ex) {

        log.error("Target Method resulted into exception, message {}", ex.getMessage());
        notificationService.error(ex.getMessage());
    }
}Code language: Java (java)

Output:

INFO  | [main] c.a.s.a.s.FileSystemStorageService:16 - Reading file: test.txt
ERROR | [main] c.a.s.a.s.LoggingAspect:17 - Target Method resulted into exception, message test.txt (No such file or directory)Code language: plaintext (plaintext)

The output shows, the advice correctly received the exception instance that was thrown from the target method.

Summary

This was an introduction to the Spring AOP AfterThrowing advice. This type of advice runs when the target method throws an exception and can access the thrown exception. Thus, the AfterThrowing advice is useful when multiple to write a common exception handler or exception post processor.

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