Backend Development 18 min read

Understanding AOP in Spring Boot: Concepts, Code Examples, and Annotation Guide

This article explains Aspect‑Oriented Programming (AOP) in Spring Boot, covering its core concepts, why it simplifies cross‑cutting concerns like logging and permission checks, provides step‑by‑step code examples of simple and advanced AOP implementations, and details the most commonly used AOP annotations.

Selected Java Interview Questions
Selected Java Interview Questions
Selected Java Interview Questions
Understanding AOP in Spring Boot: Concepts, Code Examples, and Annotation Guide

AOP (Aspect Oriented Programming) is one of the three core ideas of Spring, alongside IOC and DI, and it allows developers to separate cross‑cutting concerns such as permission validation, logging, and statistics from business logic, reducing code duplication and improving maintainability.

The AOP system consists of five key concepts: Pointcut (where to cut in), Advice (what to do and when), Aspect (the combination of pointcut and advice), Join point (a specific execution point, usually a method), and Weaving (the process of injecting the advice into the target method at runtime).

**First example – logging all GET requests** package com.mu.demo.advice; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Before; import org.aspectj.lang.annotation.Pointcut; import org.springframework.stereotype.Component; @Aspect @Component public class LogAdvice { // Define a pointcut that matches all methods annotated with @GetMapping @Pointcut("@annotation(org.springframework.web.bind.annotation.GetMapping)") private void logAdvicePointcut() {} // Execute before the matched method @Before("logAdvicePointcut()") public void logAdvice() { System.out.println("get request advice triggered"); } } The corresponding controller defines a GET endpoint /aop/getTest and a POST endpoint; only the GET method triggers the advice, demonstrating how AOP isolates the logging logic. **Second example – custom permission annotation with two advices** 1. Define a custom annotation: @Target(ElementType.METHOD) @Retention(RetentionPolicy.RUNTIME) @Documented public @interface PermissionAnnotation {} 2. First advice checks the id parameter and returns an error if it is negative. package com.example.demo; import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONObject; import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.annotation.Around; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Pointcut; import org.springframework.core.annotation.Order; import org.springframework.stereotype.Component; @Aspect @Component @Order(1) public class PermissionFirstAdvice { @Pointcut("@annotation(com.mu.demo.annotation.PermissionAnnotation)") private void permissionCheck() {} @Around("permissionCheck()") public Object permissionCheckFirst(ProceedingJoinPoint joinPoint) throws Throwable { Object[] args = joinPoint.getArgs(); Long id = ((JSONObject) args[0]).getLong("id"); if (id < 0) { return JSON.parseObject("{\"message\":\"illegal id\",\"code\":403}"); } return joinPoint.proceed(); } } 3. Second advice checks the name parameter and ensures it equals "admin". package com.example.demo; import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONObject; import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.annotation.Around; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Pointcut; import org.springframework.core.annotation.Order; import org.springframework.stereotype.Component; @Aspect @Component @Order(0) public class PermissionSecondAdvice { @Pointcut("@annotation(com.example.demo.PermissionsAnnotation)") private void permissionCheck() {} @Around("permissionCheck()") public Object permissionCheckSecond(ProceedingJoinPoint joinPoint) throws Throwable { Object[] args = joinPoint.getArgs(); Long id = ((JSONObject) args[0]).getLong("id"); String name = ((JSONObject) args[0]).getString("name"); if (!name.equals("admin")) { return JSON.parseObject("{\"message\":\"not admin\",\"code\":403}"); } return joinPoint.proceed(); } } The execution order is controlled by the @Order annotation; a lower number runs earlier. Tests show how different parameter combinations trigger the appropriate advice or return error responses. **Common AOP annotations** @Pointcut : defines where to cut, using expressions like execution() or annotation() . @Around : surrounds the target method, allowing pre‑processing, parameter modification, and post‑processing via ProceedingJoinPoint.proceed() . @Before : runs before the target method, useful for logging or statistics. @After : runs after the target method, typically for cleanup or final logging. @AfterReturning : captures the method’s return value for further processing. @AfterThrowing : handles exceptions thrown by the target method. Each annotation can be combined with custom or Spring‑provided annotations (e.g., @GetMapping , @PostMapping ) to create flexible cross‑cutting logic. In summary, AOP provides a powerful mechanism to modularize concerns that cut across multiple services, and the examples demonstrate how to implement logging, permission checks, and response handling in a Spring Boot application.

BackendJavaaopSpring BootAnnotationsAspect-Oriented Programming
Selected Java Interview Questions
Written by

Selected Java Interview Questions

A professional Java tech channel sharing common knowledge to help developers fill gaps. Follow us!

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.