Spring AOP Quick Start Guide

Spring provides method-level AOP capabilities, allowing developers to intercept specific methods and inject cross-cutting concerns. In AOP terminology, we define join points (typically method executions), advice (the logic to inject), and aspects (combining pointcuts and advice). This guide demonstrates how to set up Spring AOP using annotation-based configuration.

Creating the Service Interface and Implementation

First, create a simple service interface that defines the target method to be intercepted:

public interface UserService {
    void displayUser(User user);
}

Next, create the implementation class marked as a Spring component:

@Component
public class UserServiceImpl implements UserService {
    public void displayUser(User user) {
        System.out.println(user.toString());
    }
}

This implementation serves as the target object for AOP proxy creation. The displayUser method will act as our join point where aspect advice can be applied.

Defining the Aspect

Create an aspect class using the @Aspect annotation. Spring IoC container recognizes this as an aspect and will process it accordingly:

@Aspect
public class UserAspect {

    // Execute before the target method, passing method arguments
    @Before("execution(* com.example.aop.UserServiceImpl.displayUser(..)) && args(user, priority)")
    public void beforeAdvice(User user, int priority) {
        System.out.println("beforeAdvice executed...");
    }

    // Execute after the target method completes (finally block)
    @After("execution(* com.example.aop.UserServiceImpl.displayUser(..))")
    public void afterAdvice() {
        System.out.println("afterAdvice executed...");
    }

    // Execute only when target method returns normally
    @AfterReturning("execution(* com.example.aop.UserServiceImpl.displayUser(..))")
    public void afterReturningAdvice() {
        System.out.println("afterReturningAdvice executed...");
    }

    // Execute when target method throws an exception
    @AfterThrowing("execution(* com.example.aop.UserServiceImpl.displayUser(..))")
    public void afterThrowingAdvice() {
        System.out.println("afterThrowingAdvice executed...");
    }

    // Introduction: add new functionality to existing classes
    @DeclareParents(value = "com.example.aop.UserServiceImpl+", defaultImpl = UserValidatorImpl.class)
    public UserValidator userValidator;
}

Each advice annotation defines when the aspect logic should execute relative to the join point. The execution pattern execution(* com.example.aop.UserServiceImpl.displayUser(..)) specifies which methods should be intercepted.

Spring Configuration

Configure the Spring application context using Java-based annotations:

@Configuration
@EnableAspectJAutoProxy
@ComponentScan("com.example")
public class AppConfiguration {
    @Bean
    public UserAspect getUserAspect() {
        return new UserAspect();
    }
}

The @EnableAspectJAutoProxy annotation enables Spring's support for AspectJ-based AOP auto-proxying.

Testing the AOP Implementation

Create a test class to verify the AOP functionality:

public class Main {
    public static void main(String[] args) {
        ApplicationContext context = new AnnotationConfigApplicationContext(AppConfiguration.class);
        UserService userService = context.getBean(UserService.class);
        UserValidator validator = context.getBean(UserValidator.class);

        User user = new User();
        user.setId(1L);
        user.setUserName("John");
        user.setUserNote("John's notes");
        
        System.out.println("## Test Result");
        userService.displayUser(user);
        System.out.println("#####################");
        
        // Test exception handling
        user = null;
        userService.displayUser(user, 2);
    }
}

Expected Output

## Test Result
beforeAdvice executed...
User{id=1, userName='John', userNote='John's notes'}
1
afterReturningAdvice executed...
afterAdvice executed...
#####################
beforeAdvice executed...
afterThrowingAdvice executed...
afterAdvice executed...
Exception in thread "main" java.lang.NullPointerException
    at com.example.aop.UserServiceImpl.displayUser(UserServiceImpl.java:9)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    ...

The output demonstrates that all advice types are correctly woven into the target method acording to the defined execution order. The @Before advice executes first, followed by the target method, then @AfterReturning (on successful completion) or @AfterThrowing (on exception), and finally @After as a finally block.

This AOP implementation can now be applied to handle cross-cutting concerns such as logging, transaction management, security validation, and performance monitoring across multiple service methods.

Tags: Spring aop aspect-oriented-programming java spring-framework

Posted on Sat, 17 Oct 2026 16:32:06 +0000 by rabab.orthalis