【深入Spring】Aspectj的pointcut的表达式

一.介绍

标准的Aspectj Aop的pointcut的表达式类型是很丰富的,但是Spring Aop只支持其中的9种,外加Spring Aop自己扩充的一种一共是10种类型的表达式,分别如下。

execution:一般用于指定方法的执行,用的最多。
within:指定某些类型的全部方法执行,也可用来指定一个包。
this:Spring Aop是基于代理的,生成的bean也是一个代理对象,this就是这个代理对象,当这个对象可以转换为指定的类型时,对应的切入点就是它了,Spring Aop将生效。
target:当被代理的对象可以转换为指定的类型时,对应的切入点就是它了,Spring Aop将生效。
args:当执行的方法的参数是指定类型时生效。
@target:当代理的目标对象上拥有指定的注解时生效。
@args:当执行的方法参数类型上拥有指定的注解时生效。
@within:与@target类似,看官方文档和网上的说法都是@within只需要目标对象的类或者父类上有指定的注解,则@within会生效,而@target则是必须是目标对象的类上有指定的注解。而根据笔者的测试这两者都是只要目标类或父类上有指定的注解即可。
@annotation:当执行的方法上拥有指定的注解时生效。
bean:当调用的方法是指定的bean的方法时生效。

二.使用示例

(1) execution

execution是使用的最多的一种Pointcut表达式,表示某个方法的执行,其标准语法如下。

execution(modifiers-pattern? ret-type-pattern declaring-type-pattern? name-pattern(param-pattern) throws-pattern?)
modifiers-pattern表示方法的访问类型,public等;

ret-type-pattern表示方法的返回值类型,如String表示返回类型是String,“*”表示所有的返回类型;

declaring-type-pattern表示方法的声明类,如“com.elim..*”表示com.elim包及其子包下面的所有类型;

name-pattern表示方法的名称,如“add*”表示所有以add开头的方法名;

param-pattern表示方法参数的类型,name-pattern(param-pattern)其实是一起的表示的方法集对应的参数类型,如“add()”表示不带参数的add方法,“add()”表示带一个任意类型的参数的add方法,“add(,String)”则表示带两个参数,且第二个参数是String类型的add方法;

throws-pattern表示异常类型;其中以问号结束的部分都是可以省略的。

1、“execution(* add())”匹配所有的不带参数的add()方法。
2、“execution(public * com...add(..))”匹配所有com包及其子包下所有类的以add开头的所有public方法。
3、“execution(* *(..) throws Exception)”匹配所有抛出Exception的方法。

(2) within

within是用来指定类型的,指定类型中的所有方法将被拦截。

1、“within(com.spring.aop.service.UserServiceImpl)”匹配UserServiceImpl类对应对象的所有方法外部调用,而且这个对象只能是UserServiceImpl类型,不能是其子类型。
2、“within(com.elim..*)”匹配com.elim包及其子包下面所有的类的所有方法的外部调用。

(3) this

Spring Aop是基于代理的,this就表示代理对象。this类型的Pointcut表达式的语法是this(type),当生成的代理对象可以转换为type指定的类型时则表示匹配。基于JDK接口的代理和基于CGLIB的代理生成的代理对象是不一样的。

1、“this(com.spring.aop.service.IUserService)”匹配生成的代理对象是IUserService类型的所有方法的外部调用。

(4) target

Spring Aop是基于代理的,target则表示被代理的目标对象。当被代理的目标对象可以被转换为指定的类型时则表示匹配。

1、“target(com.spring.aop.service.IUserService)”则匹配所有被代理的目标对象能够转换为IUserService类型的所有方法的外部调用。

(5) args

args用来匹配方法参数的。

1、“args()”匹配任何不带参数的方法。
2、“args(java.lang.String)”匹配任何只带一个参数,而且这个参数的类型是String的方法。
3、“args(..)”带任意参数的方法。
4、“args(java.lang.String,..)”匹配带任意个参数,但是第一个参数的类型是String的方法。
5、“args(..,java.lang.String)”匹配带任意个参数,但是最后一个参数的类型是String的方法。

(6) @target

@target匹配当被代理的目标对象对应的类型及其父类型上拥有指定的注解时。

1、“@target(com.spring.support.MyAnnotation)”匹配被代理的目标对象对应的类型上拥有MyAnnotation注解时。

(7) @args

@args匹配被调用的方法上含有参数,且对应的参数类型上拥有指定的注解的情况。

1、“@args(com.spring.support.MyAnnotation)”匹配方法参数类型上拥有MyAnnotation注解的方法调用。如我们有一个方法add(MyParam param)接收一个MyParam类型的参数,而MyParam这个类是拥有注解MyAnnotation的,则它可以被Pointcut表达式“@args(com.elim.spring.support.MyAnnotation)”匹配上。

(8) @within

@within用于匹配被代理的目标对象对应的类型或其父类型拥有指定的注解的情况,但只有在调用拥有指定注解的类上的方法时才匹配。

1、“@within(com.spring.support.MyAnnotation)”匹配被调用的方法声明的类上拥有MyAnnotation注解的情况。比如有一个ClassA上使用了注解MyAnnotation标注,并且定义了一个方法a(),那么在调用ClassA.a()方法时将匹配该Pointcut;如果有一个ClassB上没有MyAnnotation注解,但是它继承自ClassA,同时它上面定义了一个方法b(),那么在调用ClassB().b()方法时不会匹配该Pointcut,但是在调用ClassB().a()时将匹配该方法调用,因为a()是定义在父类型ClassA上的,且ClassA上使用了MyAnnotation注解。但是如果子类ClassB覆写了父类ClassA的a()方法,则调用ClassB.a()方法时也不匹配该Pointcut。
(9) @annotation

@annotation用于匹配方法上拥有指定注解的情况。

1、“@annotation(com.spring.support.MyAnnotation)”匹配所有的方法上拥有MyAnnotation注解的方法外部调用。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值