由于Spring切面粒度最小是方法级别,而execution表达式可以用于明确指定方法放回类型、类名、方法名和参数名等与方法相关的部件,并且在Spring中,大部分需要使用AOP的业务场景也只需要达到方法级别即可,因而execution表达式的使用时最为广泛的。
语法(带问号的表示可选):
execution(modifiers-pattern? ret-type-pattern declaring-type-pattern?name-pattern(param-pattern) throws-pattern?)
如下为一个execution表达式例子:
execution(public * com..controller.*.insert*(..) java.lang.Exception)
该切点表达式将会匹配在com…controller下的所有类中,方法修饰符为public的任意返回值,并且以insert为前缀名,抛出Exception异常类型的方法。该例子使用了 ..
和 *
通配符。
*
通配符:该通配符主要用于匹配多个字符。..
通配符:该通配符表示0个或多个项,主要用于declaring-type-pattern和param-pattern中,如果用于declaring-type-pattern中,则表示匹配当前包及其子包,如果用于param-pattern中,则表示匹配0个或者多个参数。+
:匹配指定类型的子类型;仅能作为后缀放在类型模式后边。java.lang.Number+ 匹配java.lang包下的任何Number的自类型;如匹配java.lang.Integer,也匹配java.math.BigInteger within表达式的粒度为类,用来限定类(可使用通配符),表示匹配当前表达式的所有类。
语法:
within(declaring-type-pattern)
例如下面表达式表示匹配com.spring.xxx.service包及其子包下的所有类
within(com.spring.xxx.service..*)
this表达式表示目标对象被代理之后生成的代理对象和指定的类型匹配才会被拦截。target表达式表示目标对象为指定的类型才会被拦截。由此可知,this作用于代理对象,target作用于目标对象。
辣么什么是目标对象和代理对象呢?在Spring切面编程中,目标对象为业务逻辑对象,而代理多少是使用对业务逻辑进行封装包裹后而生成的对象。如果使用JDK动态代理,目标对象和代理对象为两个对象,如果是CGLib代理,则为一个对象。关于代理可以参考《》
在Spring中,this将匹配代理对象为指定类型的类,target将匹配业务对象为指定类型的类。例子如下:
this(com.spring.service.BaseService)
target(com.spring.service.BaseService)
args表达式的作用是匹配指定参数类型和数量的方法,无论其类路径或者是什么方法名称。可以使用 … 通配符,不能使用 * 。如下表达式表示匹配第一个参数为java.lang.String、其后可以为任意参数的方法。
args(java.lang.String,..)
指定匹配必须包好某个注解的类里的所有连接点,调用该目标对象的任意方法都会被拦截。
匹配目标对象的类含有指定注解,调用该目标对象的任意方法都会被拦截。
@target 和 @within 的不同点
匹配有指定注解的方法(注解作用在方法上面),被调用的方法包含指定的注解
方法参数所属的类型上有指定的注解。注意:是方法参数所属的类型上有指定的注解,不是方法参数中有注解
@args(com.spring.aop.jargs.annotation.Anno1)
@args(com.spring.aop.jargs.annotation.Anno1,com.spring.aop.jargs.annotation.Anno2)
@args(com.ms.aop.jargs.demo2.Anno1,..)