Spring AOP的args切点表达式有两种用法,一种是限制参数类型,另一种是获取目标方法参数。然而没见到将这两种用法放到一起讲解的,今天,笔者做了几个demo,做了对比。
首先,测试代码是基于springboot做的测试。引入的spring aop的依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
限制参数类型
需要注意的是,args指定的参数必须是全路径的。
代码如下:
首先创建目标类
@Component
public class Play {
public void play() {
System.out.println("瞎玩");
}
public void play(Integer num) {
System.out.println("玩数字" + num);
}
public void play(Ball ball) {
System.out.println("玩对象" + ball);
}
}
Ball是一个空的类
@Data
public class Ball {
private String name;
}
切面类:
@Component
@Aspect
public class ArgsAspect {
//@Pointcut("args(com.example.basedemo.aop.args.type.Ball)")
@Pointcut("within(com.example.basedemo.aop.args.type.Play) && args(com.example.basedemo.aop.args.type.Ball)")
public void argsTypePonintCut() {
}
@Before(" argsTypePonintCut()")
public void typeBefore() {
System.out.println("args前置拦截限制参数");
}
}
测试类:
@SpringBootTest
class BaseDemoApplicationTests {
@Autowired
Play play;
@Test
void testArgs() {
play.play();
play.play(new Ball());
}
}
运行结果如下:
瞎玩
args前置拦截限制参数
玩对象Ball(name=null)
从运行结果看出,优于限制了 运行方法的参数是Ball类型的,所以paly()方法并没有被拦截,只有play(Ball ball)方法被拦截了。
获取目标方法参数
用新的切面类
@Component
@Aspect
public class ArgsAspect {
@Pointcut("execution(* com.example.basedemo.aop.args.type.Play.play(Integer)) && args(num)")
public void argsParampointcut(Integer num) { // 参数名必须和 args()的参数名一致
}
@Before("argsParampointcut(num)")
public void paramBefore(Integer num) {//参数名也必须和切点方法的参数名一致
System.out.println("args前置拦截获取参数" + num);
}
}
测试:
@SpringBootTest
class BaseDemoApplicationTests {
@Autowired
Play play;
@Test
void testArgs() {
play.play();
play.play(1);
}
}
运行结果如下:
瞎玩
args前置拦截获取参数1
玩数字1
从运行结果来看,拦截方法获取到了目标方法的参数。