Backend Development 12 min read

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.

Spring Full-Stack Practical Cases
Spring Full-Stack Practical Cases
Spring Full-Stack Practical Cases
Mastering Spring AOP Pointcut Expressions: A Complete Guide

Expression Explanation

Environment: Spring Boot 2.3.10

The most commonly used

execution

pointcut designator is explained with its full syntax:

<code>execution(modifiers-pattern? ret-type-pattern declaring-type-pattern? name-pattern(param-pattern) throws-pattern?)</code>

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:

Spring AOP pointcut designators
Spring AOP pointcut designators

Annotation Class

<code>@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();
}</code>

Aspect Class

<code>@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("执行后...");
    }
}</code>

Custom Annotation

<code>@Target({ElementType.FIELD, ElementType.METHOD, ElementType.TYPE, ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
public @interface Pack {}
</code>

execution Pointcut

Matches method execution join points.

<code>@Pointcut("execution(* com.pack.dao..*.*(..))")
</code>

Matches any method in

com.pack.dao

package or sub‑packages, regardless of return type or parameters.

<code>@Pointcut("execution(com.pack.domain.Person com.pack.dao..*.*(..))")
</code>

Matches methods returning

com.pack.domain.Person

.

<code>@Pointcut("execution(* com.pack.dao..*.sa*(..))")
</code>

Matches method names starting with

sa

.

<code>@Pointcut("execution(* com.pack.dao..*.*(com.pack.domain.Person))")
</code>

Matches methods whose single parameter type is

Person

.

<code>@Pointcut("execution(public * com.pack.dao..*.*(..))")
</code>

Matches public methods.

<code>@Pointcut("execution(* com.pack.dao.impl.*.*(..))")
</code>

Matches any method in

com.pack.dao.impl

package.

within Pointcut

Limits matching to join points within a specific type.

<code>@Pointcut("within(com.pack..*)")
</code>

Matches any method in all classes under

com.pack

and its sub‑packages.

<code>@Pointcut("within(com.pack.dao.impl.PersonDAOImpl)")
</code>

Matches any method in

PersonDAOImpl

class.

this Pointcut

Matches when the current AOP proxy object is an instance of the specified type.

<code>@Pointcut("this(com.pack.dao.PersonDAO)")
</code>

Matches when the proxy implements

PersonDAO

.

<code>@Pointcut("this(com.pack.dao.impl.PersonDAOImpl)")
</code>

Requires CGLIB proxy; JDK proxy will not match because the proxy implements the interface, not the concrete class.

Spring AOP proxy configuration:

<code>spring:
  aop:
    proxy-target-class: false  # use JDK dynamic proxies
</code>

Setting

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.

<code>@Pointcut("target(com.pack.dao.PersonDAO)")
</code>

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).

<code>@Pointcut("execution(* com.pack..*.*(..)) && args(com.pack.domain.Person)")
</code>

Matches methods receiving a

Person

argument.

<code>@Pointcut("execution(* com.pack..*.*(..)) && args(java.lang.String, ..)")
</code>

Matches methods whose first argument is a

String

.

@within Pointcut

Matches any method within a class annotated with a specific annotation.

<code>@Pointcut("@within(com.pack.dao.Pack)")
</code>

@target Pointcut

Matches methods where the target object carries a specific annotation.

<code>@Pointcut("execution(* com.pack..*.*(..)) && @target(com.pack.dao.Pack)")
</code>

@args Pointcut

Matches methods whose arguments are annotated with a specific annotation.

<code>@Pointcut("execution(* com.pack..*.*(..)) && @args(com.pack.dao.Pack)")
</code>

@annotation Pointcut

Matches methods that are themselves annotated with a specific annotation.

<code>@Pointcut("@annotation(com.pack.dao.Pack)")
</code>

Various Advice Types

Before advice

<code>@Before("log()")
public void deBefore(JoinPoint joinPoint) throws Throwable {}
</code>

After returning advice

<code>@AfterReturning(returning = "ret", pointcut = "log()")
public void doAfterReturning(Object ret) throws Throwable {
    System.out.println("返回值:" + ret);
}
</code>

Result screenshot:

AfterReturning result
AfterReturning result

After throwing advice

<code>@AfterThrowing("log()")
public void throwss(JoinPoint jp) {
    System.out.println("抛出异常了");
}
</code>

After (finally) advice

<code>@After("log()")
public void after(JoinPoint jp) {}
</code>

Around advice

<code>@Around("log()")
public Object around(ProceedingJoinPoint pjp) throws Throwable {
    logger.info("执行前...");
    Object result = pjp.proceed();
    logger.info("执行后...");
    return result;
}
</code>

The tutorial concludes the comprehensive overview of Spring AOP pointcut expressions and advice types.

JavaSpring AOPAspect-Oriented ProgrammingPointcut Expressions
Spring Full-Stack Practical Cases
Written by

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.

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.