execution表达式是spring aop最常用、最精准的切点定义方式,通过修饰符、返回类型、类名、方法名和参数等语法元素精确匹配目标方法,并支持通配符、逻辑运算符及访问权限过滤。

Spring AOP 中的 execution 表达式是定义切点最常用、最精准的方式,它能按方法签名精确匹配目标方法。关键在于理解其语法结构,并结合实际场景合理组合修饰符、返回类型、类名、方法名和参数。
execution 表达式基本语法
execution(修饰符? 返回类型 类型声明? 方法名(参数) 异常?)
其中带 ? 的部分可省略,最常用的是:
execution(返回类型 包名.类名.方法名(参数))
例如:execution(* com.example.service.UserService.update*(..))
表示匹配 UserService 类中所有以 update 开头、任意返回类型、任意参数的方法。
用通配符提升匹配灵活性
通配符不是“偷懒”,而是精准控制匹配范围的必要手段:
-
*:匹配任意一个单词(如包名、类名、方法名、基本类型名),不能跨层级或匹配点号;
✅com.example.*.service.*Service.*(..)—— 匹配com.example下任意子包中service包里的所有*Service类的任意方法
❌com.example..*.service.*——..才支持多级包,单个*不行 -
..:匹配任意数量的包层级(用于包路径)或任意数量/类型的参数(用于方法参数);execution(* com.example..service.*.*(..))—— 匹配com.example下任意深度的service子包中任意类的任意方法 -
+:匹配该类及其所有子类(仅用于类名后,如UserService+匹配UserServiceImpl等实现类)
按访问权限和异常精准过滤
虽然不常用,但在需要严格限定时非常有用:
- 加
public限定只拦截 public 方法:execution(public * com.example.service.*.*(..)) - 排除
void方法,只拦截有返回值的:execution(!void com.example.service.*.*(..)) - 限定抛出特定异常的方法(较少用,但语法支持):
execution(* com.example.service.*.*(..) throws java.io.IOException)
组合多个 execution 实现复杂切点逻辑
单个 execution 不够用时,可用逻辑运算符组合:
-
&&(and):同时满足多个条件@Pointcut("execution(* com.example.service.UserServiceImpl.save*(..)) && args(userId, ..)")—— 匹配方法名以 save 开头,且第一个参数是userId的方法 -
||(or):满足任一即可@Pointcut("execution(* com.example.service.*.create*(..)) || execution(* com.example.service.*.update*(..))") -
!(not):取反@Pointcut("execution(* com.example.service.*.*(..)) && !execution(* com.example.service.*.get*(..))")—— 拦截 service 包下所有方法,但排除所有 get 开头的
不复杂但容易忽略:写完 expression 后务必在真实调用链中验证——比如接口代理、CGLIB 继承、private 方法不可被代理等限制,都会让看似正确的 expression 失效。优先保证目标方法是 Spring 容器管理的 Bean,且调用发生在代理对象上。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











