Monday, 3 December 2018

Spring AOP AspectJ @AfterReturning Annotation Example | Spring Tutorial

Mastering Spring AOP: @AfterReturning AspectJ Annotation Explained

🚀 LEVEL UP YOUR JAVA SKILLS - SUBSCRIBE TO RAM N JAVA!

What is @AfterReturning Annotation?

In Spring Aspect-Oriented Programming (AOP), the @AfterReturning annotation is used to define "advice" that runs after a method successfully completes its execution. Unlike general "After" advice, this specific type only triggers if the method returns normally and does not throw an exception.

Key Features and Benefits

  • Access Return Values: It allows you to intercept and use the value returned by the target method.
  • Conditional Execution: It only runs on success, making it perfect for post-processing results.
  • Cleaner Code: Keep your business logic focused by moving logging or auditing tasks into a separate Aspect class.

How to Implement It

To use this annotation, you define a method within your Aspect class and annotate it with @AfterReturning. You can specify the "pointcut" to determine which methods to watch, and use the returning attribute to capture the returned object. This gives you a clean way to log "Employee added successfully with ID: 101" without adding logging code to your service layer.

Real-World Use Cases

This is widely used for Logging successful transactions, Auditing user actions, or even Transforming data before it reaches the final caller. It ensures that your monitoring logic only fires when things go exactly as planned!


Explore More Spring AOP Tutorials from Ram N Java:


Click here to watch on Youtube:
https://www.youtube.com/watch?v=nOY9m66Ipwg&list=UUhwKlOVR041tngjerWxVccw

Click the below Image to Enlarge:
Spring AOP AspectJ @AfterReturning Annotation Example | Spring Tutorial

Spring AOP AspectJ @AfterReturning Annotation Example | Spring Tutorial

Spring AOP AspectJ @AfterReturning Annotation Example | Spring Tutorial
pom.xml

<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 http://maven.apache.org/maven-v4_0_0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.ram.core</groupId>
    <artifactId>SpringDemo</artifactId>
    <packaging>jar</packaging>
    <version>1.0-SNAPSHOT</version>
    <name>SpringDemo</name>
    <url>http://maven.apache.org</url>

    <properties>
        <spring.version>5.0.5.RELEASE</spring.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>3.8.1</version>
            <scope>test</scope>
        </dependency>

        <!-- Spring 5 dependencies -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-core</artifactId>
            <version>${spring.version}</version>
        </dependency>

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>${spring.version}</version>
        </dependency>

        <!-- Spring AOP + AspectJ -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-aop</artifactId>
            <version>${spring.version}</version>
        </dependency>
       
        <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjrt</artifactId>
            <version>1.9.1</version>
        </dependency>
       
        <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjweaver</artifactId>
            <version>1.9.1</version>
        </dependency>

    </dependencies>

</project>

EmployeeService.java

package com.ram.service;

public class EmployeeService
{
    public String addEmployee()
    {
        System.out.println("Add Employee ");
        return "Employee Peter information is added successfully";
    }

    public void modifyEmployee()
    {
        System.out.println("Modify Employee");
    }

    public void deleteEmployee()
    {
        System.out.println("Delete Employee");
    }

}

LoggingAspect.java

package com.ram.Aspect;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;

@Aspect
public class LoggingAspect
{

    @AfterReturning(
            pointcut = "execution(* com.ram.service.EmployeeService.addEmployee())",
            returning = "result")
    public void logAfterReturning(JoinPoint joinPoint, Object result)
    {

        System.out.print("logAfterReturning() is running!");
        System.out.println(", after "
                + joinPoint.getSignature().getName() + " method");
        System.out.println("Method returned value is = " + result);
        System.out.println("******");
    }

}

applicationContext.xml

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


    <aop:aspectj-autoproxy />

    <bean id="employeeService" class="com.ram.service.EmployeeService"></bean>
   
    <!-- Aspect -->
    <bean id="logAspect" class="com.ram.Aspect.LoggingAspect" />

</beans>

App.java

package com.ram.core;

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

import com.ram.service.EmployeeService;

public class App
{
    public static void main(String[] args)
    {
        ApplicationContext context = new ClassPathXmlApplicationContext(
                "applicationContext.xml");

        System.out.println("---------------------------------------");

        EmployeeService employeeService = context
                .getBean("employeeService", EmployeeService.class);

        employeeService.addEmployee();

        employeeService.modifyEmployee();

        employeeService.deleteEmployee();

    }

}

Output

Nov 09, 2018 9:28:30 AM org.springframework.context.support.AbstractApplicationContext prepareRefresh
INFO: Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@32709393: startup date [Fri Nov 09 09:28:30 IST 2018]; root of context hierarchy
Nov 09, 2018 9:28:31 AM org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
INFO: Loading XML bean definitions from class path resource [applicationContext.xml]
---------------------------------------
Add Employee
logAfterReturning() is running!, after addEmployee method
Method returned value is = Employee Peter information is added successfully
******
Modify Employee
Delete Employee

Click the below link to download the code:
https://sites.google.com/site/ramj2eev2/java_basics/SpringDemo_AfterReturning_annotation.zip?attredirects=0&d=1

Github Link:
https://github.com/ramram43210/javaee/tree/master/Spring_2018/SpringDemo_AfterReturning_annotation

Bitbucket Link:
https://bitbucket.org/ramram43210/spring/src/0b94f52191c5d2085aabe1f85d3349dd2bf0b474/Spring_2018/SpringDemo_AfterReturning_annotation/?at=master

See also:

  • All JavaEE Videos Playlist
  • All JavaEE Videos
  • All JAVA EE Links
  • Spring Tutorial
  • Servlets Tutorial
  • All Design Patterns Links
  • JDBC Tutorial
  • Java Collection Framework Tutorial
  • JAVA Tutorial
  • Kids Tutorial
  • Cooking Tutorial
  • No comments:

    Post a Comment

    Tutorials