Spring AOP AspectJ @AfterThrowing Example

In this spring aop example, we will learn to use aspectj @AfterThrowing annotation. @AfterThrowing annotated methods run after the method (matching with pointcut expression) exits by throwing an exception.

In this example, We will create simple spring application, add logging aspect and then invoke aspect methods based on pointcuts information passed in @AfterThrowing annotation.

AspectJ @AfterThrowing Annotation Usage

AspectJ @AfterThrowing advice is executed after a join point does not complete normally and end up throwing an exception.

@Aspect
public class LoggingAspect {

    @AfterThrowing ("execution(* com.howtodoinjava.app.service.impl.EmployeeManagerImpl.*(..))")
    public void logAfterThrowingAllMethods() throws Throwable { ... }
}

Often you want the advice to run only when exceptions of a given type are thrown, and you also often need access to the thrown exception in the advice body. Use the throwing attribute to both restrict matching (if desired, use Throwable as the exception type otherwise) and bind the thrown exception to an advice parameter.

@Aspect
public class LoggingAspect {

    @AfterThrowing (pointcut = "execution(* com.howtodoinjava.app.service.impl.EmployeeManagerImpl.*(..))", throwing = "ex")
    public void logAfterThrowingAllMethods(SomeCustomException ex) throws Throwable  { ... }
}

The name used in the throwing attribute must correspond to the name of a parameter in the advice method. When a method execution exits by throwing an exception, the exception will be passed to the advice method as the corresponding argument value.

A throwing clause also restricts matching to only those method executions that throw an exception of the specified type ( SomeCustomException in this case).

Project Structure

Spring AOP Project Structure
Spring AOP Project Structure

Spring AOP AspectJ Maven Dependencies

I have added spring core, spring aop and aspectj dependencies.

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd;
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.howtodoinjava</groupId>
    <artifactId>SpringAOPExamples</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>Spring AOP Examples</name>
    <dependencies>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>4.3.2.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context-support</artifactId>
            <version>4.3.2.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-aop</artifactId>
            <version>4.3.2.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjrt</artifactId>
            <version>1.8.9</version>
        </dependency>
        <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjweaver</artifactId>
            <version>1.8.9</version>
        </dependency>
    </dependencies>
</project>

Enable AspectJ Support

In XML config file, you can add aop:aspectj-autoproxy element to enable @AspectJ annotation support.

<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:aop="http://www.springframework.org/schema/aop"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
    http://www.springframework.org/schema/aop/
    http://www.springframework.org/schema/aop/spring-aop-3.0.xsd ">

    <!-- Enable @AspectJ annotation support  -->
    <aop:aspectj-autoproxy />
    
    <!-- Employee manager -->
    <bean id="employeeManager" class="com.howtodoinjava.app.service.impl.EmployeeManagerImpl" />

    <!-- Logging Aspect -->
    <bean id="loggingAspect" class="com.howtodoinjava.app.aspect.LoggingAspect" />

</beans>

Service methods on which aspects needs to be executed

EmployeeManager.java and EmployeeManagerImpl.java

public interface EmployeeManager 
{
    public EmployeeDTO getEmployeeById(Integer employeeId);

    public List<EmployeeDTO> getAllEmployee();

    public void createEmployee(EmployeeDTO employee);

    public void deleteEmployee(Integer employeeId);

    public void updateEmployee(EmployeeDTO employee);
}

public class EmployeeManagerImpl implements EmployeeManager 
{
    public EmployeeDTO getEmployeeById(Integer employeeId) 
    {
        System.out.println("Method getEmployeeById() called");
        return new EmployeeDTO();
    }

    public List<EmployeeDTO> getAllEmployee() 
    {
        System.out.println("Method getAllEmployee() called");
        return new ArrayList<EmployeeDTO>();
    }

    public void createEmployee(EmployeeDTO employee)
    {
        System.out.println("Method createEmployee() called");
        //Throwing an exception
        throw new NullPointerException("ID not found");
    }

    public void deleteEmployee(Integer employeeId) 
    {
        System.out.println("Method deleteEmployee() called");
    }

    public void updateEmployee(EmployeeDTO employee) 
    {
        System.out.println("Method updateEmployee() called");
    }
}

Write AspectJ Annotated Class and Methods

Write aspectj annotated class and methods with pointcut information.

@Aspect
public class LoggingAspect {

    @AfterThrowing (pointcut = "execution(* com.howtodoinjava.app.service.impl.EmployeeManagerImpl.*(..))", throwing = "ex")
    public void logAfterThrowingAllMethods(Exception ex) throws Throwable 
    {
        System.out.println("****LoggingAspect.logAfterThrowingAllMethods() " + ex);
    }
}

Test Spring AspectJ Configuration and Execution

Now let’s test whether above configured aspects execute on given pointcut information.

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import com.howtodoinjava.app.model.EmployeeDTO;
import com.howtodoinjava.app.service.EmployeeManager;

public class TestMain 
{
    @SuppressWarnings("resource")
    public static void main(String[] args) {
 
        ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
        EmployeeManager manager = (EmployeeManager) context.getBean("employeeManager");
 
        manager.getEmployeeById(1);
        manager.createEmployee(new EmployeeDTO());
    }
}
Method getEmployeeById() called

Method createEmployee() called

****LoggingAspect.logAfterThrowingAllMethods() java.lang.NullPointerException: ID not found

Exception in thread "main" java.lang.NullPointerException: ID not found
    at com.howtodoinjava.app.service.impl.EmployeeManagerImpl.createEmployee(EmployeeManagerImpl.java:26)

Clearly aspect advices executed on relevant jointpoints.

Happy Learning !!

References:

Spring AOP Reference
@AfterThrowing Annotation
@Aspect Annotation
AspectJ Annotation Config Example
Different Pointcut Expressions With Examples

Leave a Reply

0 Comments
Inline Feedbacks
View all comments

About Us

HowToDoInJava provides tutorials and how-to guides on Java and related technologies.

It also shares the best practices, algorithms & solutions and frequently asked interview questions.

Our Blogs

REST API Tutorial