戴着假发的程序员出品 抖音ID:戴着假发的程序员 欢迎关注
@Pointcut的表达式-@args
spring应用手册(第三部分)
限制与连接点的匹配(使用 Spring AOP 时执行方法),其中传递的实际 arguments 的运行时类型具有给定类型的注释。
看看官方给的例子:
任何连接点(仅在 Spring AOP 中执行方法),它接受一个参数,并且传递的参数的运行时类型具有@Classified annotation:
@args(com.xyz.security.Classified)
这什么意思呢,我来解释一下,就是匹配有指定的参数,并且要求传入的参数对象必须有制定的注解。
如果还不明白,看我的案例:
我们准备两个交通工具类:
小汽车Car,在Car上添加我们自定义的注解
/**
* @author 戴着假发的程序员
*
* @description
*/
@Component
@DkAnnotation
public class Car {
@Override
public void move() {
System.out.println("小汽车动起来");
}
}
卡车Truck ,在Truck上不添加我们自定义的注解
/**
* @author 戴着假发的程序员
*
* @description
*/
@Component
public class Truck {
@Override
public void move() {
System.out.println("卡车动起来");
}
}
在定义一个驾驶员类Driver,有一个drive的方法,需要传入交通工具作为参数:
/**
* @author 戴着假发的程序员
*
* @description
*/
@Component
public class Driver {
public void driveCar(Car car){
System.out.println("驾驶员开始驾驶小汽车");
car.move();
}
public void driveTruck(Truck truck){
System.out.println("驾驶员开始驾驶卡车");
truck.move();
}
}
修改Aspect类配置:
/**
* @author 戴着假发的程序员
*
* @description
*/
@Component //将当前bean交给spring管理
@Aspect //定义为一个AspectBean
public class DkAspect {
//使用@arg配置传入参数有DkAnnotation注解的方法
@Pointcut("@args(com.st.dk.demo7.annotations.DkAnnotation)")
private void pointCut1(){}
//定义一个前置通知
@Before("pointCut1()")
private static void befor(){
System.out.println("---前置通知---");
}
}
测试:
@Test
public void testAopPoint_args(){
ApplicationContext ac =
new AnnotationConfigApplicationContext(Appconfig.class);
//获取Car
Car car = ac.getBean(Car.class);
//获取Truck
Truck truck = ac.getBean(Truck.class);
//获取Driver
Driver driver = ac.getBean(Driver.class);
//传入car
driver.driveCar(car);
//传入truck
driver.driveTruck(truck);
}
结果:
我们发现driveCar方法会被增强,因为Car类有注解@DkAnnotation
这里我们再列举以下父子类已经接口实现的情况:
父子类的情况:看图:
图中T1~T4有继承关系。 method1参数类型T1,method2参数类型T2。
情况1:我们在T1上添加对应的注解,其他子类不添加注解。
则T1的所有子类对象包括T1本身传入method1都生效。传入method2都不会被匹配。
情况2:我们再T2上添加注解其他的类不添加注解,
那么method2中传入T2,T3,T4都会被匹配。 method1传入任何参数都不会被匹配。
结论就是,我们添加在对应的方法指定类型上时,这个类型本身和其子类都会生效,其他情况都不会匹配。
接口的情况和继承关系的情况一致。