Mastering Spring AOP: From Basics to Advanced Real‑World Examples
This article introduces Aspect‑Oriented Programming in Spring, explains core concepts such as pointcut, advice, aspect, join point and weaving, and provides step‑by‑step code examples—including a simple @GetMapping logger, a custom permission annotation with multiple aspects, and detailed usage of @Pointcut, @Around, @Before, @After, @AfterReturning and @AfterThrowing annotations—illustrated with diagrams and runnable snippets.
Understanding AOP
1.1 What is AOP
AOP (Aspect Oriented Programming) is one of Spring's core concepts, alongside IoC and DI.
It helps separate cross‑cutting concerns such as permission checks, logging, and statistics from business logic, avoiding repetitive code.
By extracting these concerns into aspects, the code becomes cleaner and more maintainable.
1.2 AOP System and Concepts
AOP performs three kinds of work: where to cut in (pointcut), when to cut (before/after), and what to do (advice).
Pointcut: defines where the aspect is applied. Advice: the action to perform (before, after, around, etc.). Aspect: combination of pointcut and advice. Joint point: a specific execution point, usually a method. Weaving: the process of linking aspect code with target code.
2 AOP Examples
Project code is available at
https://github.com/ThinkMugz/aopDemo
2.1 First Example
All get requests trigger a console message before execution.
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>Step 1: Create an aspect class
package com.mu.demo.advice;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;
@Aspect
@Component
public class LogAdvice {
@Pointcut("@annotation(org.springframework.web.bind.annotation.GetMapping)")
private void logAdvicePointcut() {}
@Before("logAdvicePointcut()")
public void logAdvice() {
System.out.println("get请求的advice触发了");
}
}Step 2: Create a controller
package com.mu.demo.controller;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import org.springframework.web.bind.annotation.*;
@RestController
@RequestMapping("/aop")
public class AopController {
@GetMapping("/getTest")
public JSONObject aopTest() {
return JSON.parseObject("{\"message\":\"SUCCESS\",\"code\":200}");
}
@PostMapping("/postTest")
public JSONObject aopTest2(@RequestParam("id") String id) {
return JSON.parseObject("{\"message\":\"SUCCESS\",\"code\":200}");
}
}Calling the GET endpoint prints the advice message; the POST endpoint does not, confirming the pointcut targets only @GetMapping methods.
2.2 Second Example – Custom Annotation
Define a custom annotation PermissionsAnnotation and two aspect classes to perform sequential permission checks.
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface PermissionAnnotation {}First Aspect
package com.example.demo;
import com.alibaba.fastjson.*;
import org.aspectj.lang.*;
import org.aspectj.lang.annotation.*;
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();
}
}Second Aspect
package com.example.demo;
import com.alibaba.fastjson.*;
import org.aspectj.lang.*;
import org.aspectj.lang.annotation.*;
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();
String name = ((JSONObject) args[0]).getString("name");
if (!"admin".equals(name)) {
return JSON.parseObject("{\"message\":\"not admin\",\"code\":403}");
}
return joinPoint.proceed();
}
}Applying @PermissionsAnnotation on a controller method triggers both aspects; execution order is controlled by @Order (lower value runs first).
3 AOP‑Related Annotations
3.1 @Pointcut
Defines where an aspect applies. Examples use execution() and annotation() expressions.
@Aspect
@Component
public class LogAspectHandler {
@Pointcut("execution(* com.mutest.controller..*.*(..))")
public void pointCut() {}
}3.2 @Around
Wraps the target method, allowing pre‑ and post‑processing, argument modification, and return‑value alteration.
@Around("pointCut()")
public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
// pre‑logic
Object result = joinPoint.proceed();
// post‑logic
return result;
}3.3 @Before
Runs before the matched method, useful for logging or gathering request data.
@Before("pointCut()")
public void doBefore(JoinPoint joinPoint) {
// log method name, URL, IP, etc.
}3.4 @After
Runs after the matched method, typically for cleanup or final logging.
@After("pointCut()")
public void doAfter(JoinPoint joinPoint) {
// log completion
}3.5 @AfterReturning
Captures the method’s return value for further processing.
@AfterReturning(pointcut = "pointCut()", returning = "result")
public void doAfterReturning(JoinPoint joinPoint, Object result) {
// enhance or log result
}3.6 @AfterThrowing
Handles exceptions thrown by the target method.
@AfterThrowing(pointcut = "pointCut()", throwing = "ex")
public void afterThrowing(JoinPoint joinPoint, Throwable ex) {
// log exception
}These annotations together provide a powerful toolkit for modularizing cross‑cutting concerns in Spring applications.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
Java Interview Crash Guide
Dedicated to sharing Java interview Q&A; follow and reply "java" to receive a free premium Java interview guide.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
