Mastering Spring Boot 3 AOP: Advanced Pointcut Techniques & Advice Ordering
This article explains how to create simple AOP aspects in Spring Boot 3, then dives into complex scenarios such as combining pointcut expressions, sharing pointcuts across aspects, programmatic pointcut composition, and controlling advice execution order, providing clear code examples for each case.
1. Introduction
Creating an aspect in a Spring Boot project is straightforward; the example below shows a basic aspect with a pointcut and an around advice.
<code>@Component
@Aspect
public class LogAspect {
// Define pointcut
@Pointcut("execution(* com.pack..*.*(..))")
private void log() {}
// Define around advice
@Around("log()")
public Object process(ProceedingJoinPoint pjp) throws Throwable {
// TODO
}
}
</code>The simple definition covers most common scenarios, but more complex requirements arise.
Complex conditions that combine multiple criteria to decide whether to execute a specific advice.
Scenarios where any one of several conditions should trigger the advice.
Sharing pointcut expressions across multiple aspects.
Programmatically defining composite pointcuts.
Controlling the execution order of advices.
2. Practical Cases
2.1 Combine Pointcut Expressions
You can use && , || and ! to combine pointcut expressions, or reference named pointcuts. Example:
<code>@Pointcut("execution(public com.pack..*.query*(..))")
private void pc1() {}
@Pointcut("@annotation(com.pack.Pack)")
private void pc2() {}
// Both must match
// @Pointcut("pc1() && pc2()")
// Either matches
@Pointcut("pc1() || pc2()")
private void pc() {}
</code>For complex pointcuts, break them into smaller expressions and combine them with logical operators.
2.2 Share Pointcuts
In large applications, multiple aspects may need the same pointcut. Spring recommends defining a common pointcut class:
<code>public class CommonPointcuts {
@Pointcut("execution(* com.pack..*.*(..))")
private void log() {}
@Pointcut("@annotation(com.pack.aop.create.Pack)")
public void auth() {}
}
</code>Aspects can then reference these pointcuts:
<code>@Aspect
public class LogAspect {
@Around("com.pack.aop.create.CommonPointcuts.log()")
public Object around(ProceedingJoinPoint pjp) throws Throwable {
System.out.println("before...");
Object ret = pjp.proceed();
System.out.println("after...");
return ret;
}
}
</code>Note that the visibility of the pointcut method matters: private pointcuts work only within the same class, protected within the same package hierarchy, and public everywhere.
2.3 Programmatic Pointcut Composition
Beyond declarative expressions, you can compose pointcuts programmatically using ComposablePointcut :
<code>Pointcut p1 = new Pointcut() {
public MethodMatcher getMethodMatcher() {
return method -> method.getName().startsWith("query");
}
public ClassFilter getClassFilter() { return ClassFilter.TRUE; }
};
Pointcut p2 = new Pointcut() {
public MethodMatcher getMethodMatcher() {
return (method, targetClass) -> targetClass.getPackageName().startsWith("com.pack");
}
public ClassFilter getClassFilter() { return ClassFilter.TRUE; }
};
ComposablePointcut composable = new ComposablePointcut(p1);
composable.union(p2); // any matches
composable.intersection(p2); // both must match
</code>These composed pointcuts can be used like any other pointcut expression.
2.4 Advice Execution Order
Given the following advices:
<code>@Before("log()")
public void before() {}
@After("log()")
public void after() {}
@AfterReturning("log()")
public void afterReturning() {}
@Around("log()")
public Object around(ProceedingJoinPoint pjp) {}
</code>When no exception occurs, the execution sequence is:
<code>around start...
before...
# target method call
afterReturning...
after...
around end...
</code>If multiple advices of the same type exist, Spring orders them by method name alphabetically:
<code>@Before("log()")
public void log1() {}
@Before("log()")
public void log2() {}
</code>Output:
<code>log1...
log2...
</code>Renaming the methods changes the order accordingly.
Spring Full-Stack Practical Cases
Full-stack Java development with Vue 2/3 front-end suite; hands-on examples and source code analysis for Spring, Spring Boot 2/3, and Spring Cloud.
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.