How to Implement AOP in Spring Boot Application (original) (raw)

Aspect-Oriented Programming (AOP) in Spring Boot is used to separate cross-cutting concerns like logging, security, and transaction management from business logic. It improves code modularity by applying these concerns across multiple layers without modifying the core functionality. Spring Boot simplifies AOP integration using annotations and auto-configuration.

Types of AOP Advice in Spring

Advice-in-AOP

1. @Around

It executes both before and after the target method. The first parameter must be of type ProceedingJoinPoint, and it must invoke the proceed() method to continue the target method’s execution.

Java `

@Pointcut("execution(* com.gfg.examples.service.ServiceExample.*(..))") private void printLogs() {}

@Around("printLogs()") public void logsAroundAdvice(ProceedingJoinPoint joinPoint) throws Throwable { System.out.println("Before invoking method: " + joinPoint.getSignature().getName()); try { joinPoint.proceed(); } finally { System.out.println("After invoking method: " + joinPoint.getSignature().getName()); } }

`

**Use Cases:

2. @Before

Executes before the target method is invoked. If @Around advice exists, its “before” portion executes first, followed by @Before.

Java `

@Before("execution(* com.gfg.examples.service.ServiceExample.*(..))") public void logBeforeMethod() { System.out.println("Executing @Before advice before the target method."); }

`

**Use Case: Performing input validation or pre-condition checks before a method executes.

3. @After

Executes after the method execution, regardless of its outcome (successful or exception). If @Around advice exists, its “after” part executes first.

**Sample code snippet:

Java `

@After("execution(* com.gfg.examples.service.ServiceExample.*(..))") public void logAfterMethod() { System.out.println("Executing @After advice after the target method."); }

`

**Use Case: Performing resource cleanup, sending notifications, or closing database connections.

4. @AfterReturning

Executes only when the method successfully returns a result. It can capture the return value of the method.

Java `

@AfterReturning( value = "execution(* com.gfg.examples.service.ServiceExample.*(..))", returning = "result") public void logAfterReturning(JoinPoint joinPoint, Object result) { System.out.println("Method " + joinPoint.getSignature().getName() + " returned: " + result); }

`

****Use Case:**Logging successful operations or triggering dependent actions after a successful method call.

5. @AfterThrowing

Executes only when a method throws an exception. It helps log or handle exceptions globally.

Java `

@AfterThrowing( value = "execution(* com.gfg.examples.service.ServiceExample.*(..))", throwing = "ex") public void logAfterThrowing(JoinPoint joinPoint, Exception ex) { System.out.println("Exception in method: " + joinPoint.getSignature().getName()); System.out.println("Exception Message: " + ex.getMessage()); }

`

**Use Case: Error logging, alert notifications, or rollback operations in case of failure.

Steps to Implement AOP in Spring Boot Application

Step 1: Create Spring Boot Project

**Project Structure:

Project Structure

Project Structure

Step 2: Configure pom.xml

**pom.xml

XML `

4.0.0 org.springframework.boot spring-boot-starter-parent 2.2.2.RELEASE com.gfg.examples aop-example 0.0.1-SNAPSHOT Demo project for Spring Boot AOP

<properties>
    <java.version>1.8</java.version>
</properties>

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-aop</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <scope>test</scope>
    </dependency>
</dependencies>

<build>
    <plugins>
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
        </plugin>
    </plugins>
</build>

`

**Step 3: Create Service Class

**ServiceExample.java

Java `

package com.gfg.examples.service;

import org.springframework.stereotype.Service;

@Service public class ServiceExample {

public void getAccountBalance(String employeeAccountNumber) {
    System.out.println("Inside getAccountBalance() method");
    if ("Emp1212".equals(employeeAccountNumber)) {
        System.out.println("Total balance: 50,000");
    } else {
        System.out.println("Invalid account number.");
    }
}

public String employeeStatus(String employeeNumber) {
    System.out.println("Inside employeeStatus() method");
    if ("emp12345".equals(employeeNumber)) {
        System.out.println(employeeNumber + " is active");
        return "active";
    } else {
        System.out.println(employeeNumber + " is inactive");
        return "inactive";
    }
}

public String eligibilityForPromotion(int promotionExamMarks) {
    System.out.println("Inside eligibilityForPromotion() method");
    if (promotionExamMarks >= 650) {
        System.out.println("Eligible for promotion");
        return "eligible";
    } else {
        System.out.println("Not eligible for promotion");
        return "not eligible";
    }
}

}

`

**Step 4: Create Aspect Class

**ImplementationOfDifferentAspect.java

Java `

package com.gfg.examples.aspect;

import org.aspectj.lang.JoinPoint; import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.annotation.*; import org.springframework.stereotype.Component;

@Aspect @Component public class ImplementationOfDifferentAspect {

@Pointcut("execution(* com.gfg.examples.service.ServiceExample.*(..))")
private void serviceMethods() {}

@Before("serviceMethods()")
public void logBefore() {
    System.out.println("Executing @Before advice before service method.");
}

@After("serviceMethods()")
public void logAfter() {
    System.out.println("Executing @After advice after service method.");
}

@AfterReturning(value = "serviceMethods()", returning = "result")
public void logAfterReturning(JoinPoint joinPoint, Object result) {
    System.out.println("Method returned successfully: " + joinPoint.getSignature().getName());
}

@AfterThrowing(value = "serviceMethods()", throwing = "ex")
public void logAfterThrowing(JoinPoint joinPoint, Exception ex) {
    System.out.println("Exception in method: " + joinPoint.getSignature().getName());
    System.out.println("Error: " + ex.getMessage());
}

@Around("serviceMethods()")
public void logAround(ProceedingJoinPoint joinPoint) throws Throwable {
    System.out.println("Before executing method: " + joinPoint.getSignature().getName());
    joinPoint.proceed();
    System.out.println("After executing method: " + joinPoint.getSignature().getName());
}

}

`

**Step 5: Enable AOP

**ImplementationOfDifferentAdvice.java

Java `

package com.gfg.examples;

import com.gfg.examples.service.ServiceExample; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.context.ConfigurableApplicationContext; import org.springframework.context.annotation.EnableAspectJAutoProxy;

@SpringBootApplication @EnableAspectJAutoProxy public class ImplementationOfDifferentAdvice {

public static void main(String[] args) {
    ConfigurableApplicationContext context =
            SpringApplication.run(ImplementationOfDifferentAdvice.class, args);

    ServiceExample service = context.getBean(ServiceExample.class);

    service.employeeStatus("emp12345");
    service.getAccountBalance("Emp1212");
    service.eligibilityForPromotion(650);

    context.close();
}

}

`


**Step 6: Run the Application

**Output:

Output

Output

Step 7: Observe Output

AOP advices execute automatically: