Spring AOP 中提供了丰富的切点表达式用于描述相对应的增强方法,其中@args
是其中一种基于请求参数的增强逻辑。
@args
表达式是用于限制目标方法参数的,与args
类似。区别在于@args
限制的是目标方法参数对象上所添加的注解。
args
表达式用于限制 目标方法
在运行过程中传入的参数对象类型
,@args
实现了类似的效果,但是相对于args
,@args
限制了 目标方法
在运行过程中传入的参数对象类型上面所添加的注解。
需要注意的是,这两个表达式限制的对象是方法调用时传入的参数对象类型,而不是方法定义时定义的参数对象类型。
示例
@Retention(RetentionPolicy.RUNTIME)
@Target(value = {ElementType.PARAMETER,ElementType.TYPE})
public @interface DemoAnnotation {
}
//试验组 User1 用于演示 @args 表达式的效果
@Data
@DemoAnnotation
public class User1{
private String name;
}
// 对照组 User2 用于演示 args 表达式的效果
@Data
public class User2{
private String name;
}
@Slf4j
@Service
public class DemoService{
// 由于 args 与 @args 与方法定义时参数无关,
// 这里定义传入参数类型为 Object 可以同样满足两个表达式
public void method1(Object obj){
log.info("the parameter type is {}",obj.getClass().getName());
}
}
@Slf4j
@Component
@Aspect
public class DemoAspect{
// 用于限制切点方法的范围来避免切片范围过大从而导致 Spring Boot 启动失败
@Pointcut("execution(* com.example.service..*.*(..)")
public void cut(){}
// 演示 args 的限制效果
@Before("cut() && args(com.example.dto.User2)")
public void argsExample(JointPoint jointPoint){
log.info("{}() executed by args(),the param is {}",joinPoint.getSignature().getName(),joinPoint.getArgs()[0]);
}
// 演示 @args 的限制效果
@Before("cut() && @args(com.example.annotation.DemoAnnotation))")
public void annoArgsExample(JointPoint jointPoint){
log.info("{}() executed by @args(),the param is {}",joinPoint.getSignature().getName(),joinPoint.getArgs()[0]);
}
}
@SpringBootApplication
@EnableAspectJAutoProxy
public class DemoApplication{
public static void main(String[] args){
SpringApplication.run(DemoApplication.class, args);
final DemoService service = run.getBean(DemoService.class);
final User1 user1 = new User1();
user1.setName("ghimi");
service.method1(user1);
final User2 user2 = new User2();
user2.setName("ghimi");
service.method1(user2);
}
}
执行结果:
参考资料
springboot之aop切面execution
Spring AOP中使用args表达式访问目标方法的参数
Aspect Oriented Programming with Spring