Spring AOP AspectJ @AfterReturning Annotation Example

This Spring AOP tutorial will teach us to use AspectJ @AfterReturning annotation. An @AfterReturning annotated method runs after the advised method when the advised method completes normally and does not throw any exception.

In this example, we will create a simple Spring application, add a logging aspect, and then invoke aspect methods based on pointcuts information passed in @AfterReturning annotation.

Unlike @Around, which encapsulates the entire method invocation, @AfterReturning specifically targets scenarios where a method finishes without encountering exceptions.

1. AspectJ @AfterReturning Annotation Usage

AspectJ @AfterReturning advice is executed after a joinpoint completes normally, for example, if the method returns without throwing an exception. This annotation is particularly useful for scenarios where post-processing, logging, or additional actions are required only upon successful method execution.

import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

@Aspect
@Component
  public class LoggingAspect {

  private static final Logger logger = LoggerFactory.getLogger(LoggingAspect.class);

  @AfterReturning(pointcut = "execution(* com.howtodoinjava.core.aop.service.EmployeeService.*(..))")
  public void afterReturningAdvice() {
    
    // Custom logic after the method successfully returns
    logger.info("After returning advice: Processing the result - " + result);
  }
}

The equivalent XML configuration is:

<!-- Enable AspectJ auto proxy -->
<aop:aspectj-autoproxy />

<!-- Define the aspect -->
<bean id="loggingAspect" class="com.example.aspect.LoggingAspect" />

<!-- Configure the aspect and pointcut -->
<aop:config>
    <aop:aspect id="afterReturningAspect" ref="loggingAspect">
        <aop:pointcut id="afterReturningPointcut"
                      expression="execution(* com.howtodoinjava.core.aop.service.EmployeeService.*(..))" />
        <aop:after-returning method="afterReturningAdvice"
                             pointcut-ref="afterReturningPointcut"
                             returning="result" />
    </aop:aspect>
</aop:config>

2. Handling Return Value

Sometimes we need access the actual return value that was returned from the advised method. We can get that return value as shown using ‘returning‘ attribute inside @AfterReturning annotation.

The name used in the returning attribute must correspond to the name of a parameter in the advice method. When a method execution returns, the return value will be passed to the advice method as the corresponding argument value.

@AfterReturning(pointcut = "...", returning = "result")
public void afterReturningAdvice(Object result) {

	//...
}

Please note that any ‘returning‘ clause also restricts matching to only those method executions that return a value of the specified type (Object or its subtypes in this case, which will match any return value).

3. Demo

When we run any method in the class com.howtodoinjava.core.aop.service.EmployeeService then we can see that the afterReturningAdvice() is executed after it is completed.

import com.howtodoinjava.core.demo.beans.Employee;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

@Service
public class EmployeeService {

  private static final Logger logger = LoggerFactory.getLogger(EmployeeService.class);

  public Employee save(Employee employee) {
    logger.info("Saving the Employee...");
    return employee;
  }
}

Let’s run a method and verify the output.

import com.howtodoinjava.core.aop.service.EmployeeService;
import com.howtodoinjava.core.demo.beans.Employee;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

public class Main {

  public static void main(String[] args) {
    AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);

    EmployeeService employeeService = context.getBean(EmployeeService.class);
    employeeService.save(new Employee());

    context.close();
  }
}

The program output is:

2023-11-27T12:07:49.261+0530 INFO Saving the Employee...
2023-11-27T13:54:03.398+0530 INFO After returning advice: Processing the result - Employee(id=0, name=null)

4. Maven

To get the @AfterReturning annotation working, we need to ensure that Spring AOP is setup correctly. So make sure we have the following dependencies:

<dependency>
  <groupId>org.springframework</groupId>
  <artifactId>spring-context</artifactId>
  <version>6.1.1</version>
</dependency>

<dependency>
  <groupId>org.springframework</groupId>
  <artifactId>spring-aop</artifactId>
  <version>6.1.1</version>
</dependency>

<dependency>
  <groupId>org.aspectj</groupId>
  <artifactId>aspectjweaver</artifactId>
  <version>1.9.20</version>
</dependency>

5. Enabling AOP

Also, we must enable the AOP support to @Aspect annotation to work.

import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.EnableAspectJAutoProxy;

@Configuration
@EnableAspectJAutoProxy
@ComponentScan
public class AppConfig {
  //...
}

6. Conclusion

The @AfterReturning annotation in Spring AOP with AspectJ is an way method for executing custom logic for post-processing tasks after a method successfully returns. We learned to use this annotation and capture the method return value with an example.

Happy Learning !!

Soure Code on Github

Comments

Subscribe
Notify of
guest
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.