@args 用于匹配实参运行时类型标注指定注解的方法,要求注解在实参类上且 Retention 为 RUNTIME;语法为 @args(注解全限定名),多个参数任一满足即匹配,不关心位置。

@args 用于匹配目标方法的**实际参数运行时类型**上标注了指定注解的方法,不是匹配参数声明类型上的注解(那是 @annotation 或 @within 的职责)。关键点是:Spring AOP 在织入时会检查方法调用时传入的**实参对象的类上是否标注了该注解**。
语法与基本写法
格式为:@args(全限定类名) 或 @args(注解类名)(需确保在切点表达式上下文中能解析到该注解类)。
- 注解必须作用于参数的实际运行时类型(即实参对象的 class),而非形参声明类型
- 注解需是
@Retention(RetentionPolicy.RUNTIME),否则运行时不可见 - 多个参数时,只要任意一个参数的运行时类型标有该注解,就匹配成功(不是全部)
正确示例:匹配带 @Validated 参数的方法
假设你有一个自定义注解:
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface SecuredData {}
实体类上加该注解:
立即学习“Java免费学习笔记(深入)”;
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
@SecuredData
public class UserRequest { ... }
服务方法接收该类型实例:
public void process(UserRequest request) { ... }
切点写法:
@Pointcut("@args(com.example.SecuredData)")
public void securedDataMethod() {}
当调用 process(new UserRequest()) 时触发——因为 new UserRequest() 实例的类 UserRequest 上有 @SecuredData。
常见误区与避坑
- 不要写成 @args(UserRequest):@args 后必须是注解类型,不是普通类
- 不适用于接口或抽象类上的注解:@args 检查的是实参具体实例的类,若传的是接口实现类,注解必须打在实现类上,而非接口
- 无法区分参数位置:@args 不关心是第几个参数,只看是否有任一参数满足条件
- 如果想限定“第一个参数带注解”,需配合参数绑定(如
args(param))+ 类型检查,但 @args 本身不支持位置约束
替代方案参考
若需更精细控制(如某位置参数类型含注解),可组合使用:
-
execution(* *(..)) && args(param)+ 在 advice 中手动检查param.getClass().isAnnotationPresent(SecuredData.class) - 用 @annotation 匹配方法自身标注的注解
- 用 @within 匹配目标类(非参数)上有注解的整个类的所有方法

















