Mastering Spring AOP Pointcut Expressions: A Complete Guide
This article explains the syntax and components of Spring AOP pointcut expressions, demonstrates how to use various pointcut designators such as execution, within, this, target, args, @within, @target, @args, and @annotation, and provides practical code examples with advice types.
Expression Explanation
Environment: Spring Boot 2.3.10
The most commonly used execution pointcut designator is explained with its full syntax:
execution(modifiers-pattern? ret-type-pattern declaring-type-pattern? name-pattern(param-pattern) throws-pattern?)modifiers-pattern : optional method modifiers (public, private, protected).
ret-type-pattern : required return type, usually * for any type.
declaring-type-pattern : optional class pattern.
name-pattern : required method name pattern.
param-pattern : required parameter pattern.
throws-pattern : optional exception pattern.
All parts except the returning type pattern, the name pattern, and the parameters pattern are optional. The returning type pattern determines the method's return type needed for a join point to match. * matches any return type. A fully‑qualified type name matches only that specific return type. The name pattern matches the method name; * can be used as a wildcard. Parameter patterns: () matches no parameters, (..) matches any number, (*) matches one parameter of any type, (* ,String) matches two parameters where the second must be a String .
Spring AOP Supported Pointcut Designators
The following image lists the pointcut designators supported by Spring AOP:
Annotation Class
@Component
public class PersonDAOImpl implements PersonDAO {
private static Logger logger = LoggerFactory.getLogger(PersonDAOImpl.class);
public void save(Person person) {
logger.info("save method invoke...");
}
public Person findById(Integer id) {
logger.info("findById method invoke...");
return new Person(id, "姓名" + new Random().nextInt(10000));
}
public int countPersons() {
logger.info("countPersons method invoke...");
return new Random().nextInt(1000);
}
}
public interface PersonDAO {
void save(Person person);
Person findById(Integer id);
int countPersons();
}Aspect Class
@Aspect
@Component
public class PointcutAspect {
private static Logger logger = LoggerFactory.getLogger(PointcutAspect.class);
@Pointcut("execution(* com.pack.dao..*.*(..))")
private void log() {}
@Around("log()")
public void around(ProceedingJoinPoint pjp) throws Throwable {
logger.info("执行前...");
pjp.proceed();
logger.info("执行后...");
}
}Custom Annotation
@Target({ElementType.FIELD, ElementType.METHOD, ElementType.TYPE, ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
public @interface Pack {}execution Pointcut
Matches method execution join points.
@Pointcut("execution(* com.pack.dao..*.*(..))")Matches any method in com.pack.dao package or sub‑packages, regardless of return type or parameters.
@Pointcut("execution(com.pack.domain.Person com.pack.dao..*.*(..))")Matches methods returning com.pack.domain.Person.
@Pointcut("execution(* com.pack.dao..*.sa*(..))")Matches method names starting with sa.
@Pointcut("execution(* com.pack.dao..*.*(com.pack.domain.Person))")Matches methods whose single parameter type is Person.
@Pointcut("execution(public * com.pack.dao..*.*(..))")Matches public methods.
@Pointcut("execution(* com.pack.dao.impl.*.*(..))")Matches any method in com.pack.dao.impl package.
within Pointcut
Limits matching to join points within a specific type.
@Pointcut("within(com.pack..*)")Matches any method in all classes under com.pack and its sub‑packages.
@Pointcut("within(com.pack.dao.impl.PersonDAOImpl)")Matches any method in PersonDAOImpl class.
this Pointcut
Matches when the current AOP proxy object is an instance of the specified type.
@Pointcut("this(com.pack.dao.PersonDAO)")Matches when the proxy implements PersonDAO.
@Pointcut("this(com.pack.dao.impl.PersonDAOImpl)")Requires CGLIB proxy; JDK proxy will not match because the proxy implements the interface, not the concrete class.
Spring AOP proxy configuration:
spring:
aop:
proxy-target-class: false # use JDK dynamic proxiesSetting false uses JDK proxies (interface‑based) and may cause weaving failures for this pointcuts targeting concrete classes. Setting true uses CGLIB proxies (class‑based) and enables successful weaving.
target Pointcut
Matches when the target object (the actual bean) is of the specified type.
@Pointcut("target(com.pack.dao.PersonDAO)")Matches any method where the underlying bean implements PersonDAO, regardless of proxy type.
args Pointcut
Matches methods whose arguments are of the given type(s).
@Pointcut("execution(* com.pack..*.*(..)) && args(com.pack.domain.Person)")Matches methods receiving a Person argument.
@Pointcut("execution(* com.pack..*.*(..)) && args(java.lang.String, ..)")Matches methods whose first argument is a String.
@within Pointcut
Matches any method within a class annotated with a specific annotation.
@Pointcut("@within(com.pack.dao.Pack)")@target Pointcut
Matches methods where the target object carries a specific annotation.
@Pointcut("execution(* com.pack..*.*(..)) && @target(com.pack.dao.Pack)")@args Pointcut
Matches methods whose arguments are annotated with a specific annotation.
@Pointcut("execution(* com.pack..*.*(..)) && @args(com.pack.dao.Pack)")@annotation Pointcut
Matches methods that are themselves annotated with a specific annotation.
@Pointcut("@annotation(com.pack.dao.Pack)")Various Advice Types
Before advice
@Before("log()")
public void deBefore(JoinPoint joinPoint) throws Throwable {}After returning advice
@AfterReturning(returning = "ret", pointcut = "log()")
public void doAfterReturning(Object ret) throws Throwable {
System.out.println("返回值:" + ret);
}Result screenshot:
After throwing advice
@AfterThrowing("log()")
public void throwss(JoinPoint jp) {
System.out.println("抛出异常了");
}After (finally) advice
@After("log()")
public void after(JoinPoint jp) {}Around advice
@Around("log()")
public Object around(ProceedingJoinPoint pjp) throws Throwable {
logger.info("执行前...");
Object result = pjp.proceed();
logger.info("执行后...");
return result;
}The tutorial concludes the comprehensive overview of Spring AOP pointcut expressions and advice types.
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.
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.
