AspectJ5.0的切点表达式由关键字和操作参数组成。
如 execution(* greetTo(..)), excution是关键字, "* greetTo(..)"为操作函数。
为了描述方便,将excution称为函数,而将匹配串"* greetTo(..)"称为函数的入参。
Spring支持9个@AspectJ的切点表达式函数,根据描述对象的不同,大致分为4个类型:
1、方法切点函数:通过描述目标类方法的信息定义连接点。
函数 | 入参 | 说明 |
execution() | 方法匹配模式串 | 表示满足某一匹配模式的所有目标类方法连接点 |
@annotation | 方法注解类名 | 表示标注了特定注解的目标类方法连接点 |
2、方法入参切点函数:通过描述目标类方法入参的信息定义连接点。
args() | 类名 | 通过判别目标类方法运行时入参对象的类型定义指定连接点, 可以匹配本类和本类的子类 args(com.waiter) 相当于 args(com.waiter+) |
@args() | 类型注解类名 | 通过判别目标类方法运行时入参对象的类是否标注特定注解 来指定连接点 |
arg(com.waiter) 相当于 execution(* *(com.waiter+))
@args()说明:
类的继承关系: T0 T1 T2 T3
假如目标类方法的签名为fun(T1 t),切面的切点是@args(M),T2标注了注解@M,当传入T2 T3时,匹配。
假如fun(T1 t),@args(M), T0标注了注解@M,当传入T1 T2 T3时,均不匹配!
3、目标类切点函数:通过描述目标类类型的信息定义连接点
within() | 类名匹配串 | 表示特定域下的所有连接点,如within(com.service.*)表示service包中所有类的所有方法,within没有默认+功能,即没有默认子类 |
target() | 类名 | 假如目标类按类型匹配于指定类,则目标类的所有连接点匹配这个切点。如通过target(com.Waiter)定义的切点,Waiter及Waiter实现类中的所有连接点都匹配该切点 |
@target(M) 匹配标注了 @M注解的目标类
@within(M) 匹配标注了 @M注解的目标类及其子类
@within(M) 和@target(M),如果@M标注在注解上,则无效。
再函数入参中使用通配符
有些函数的入参可以接受通配符,@AspectJ支持3种通配符。
1、* :匹配任意字符,但它只能匹配上下文中的一个元素
2、.. : 匹配任意字符,可以匹配上下文中的多个元素, 但在表示类时,必须和*联合使用,而在表示入参时单独使用。
3、 + :表示按类型匹配指定类的所有类,必须跟在类名后面,继承或扩展指定类的所有类,同时还包括指定类本身。
@AspectJ按照其是否支持函数,以及支持的程度,可以分为3类
1、支持所有的通配符:execution() 和 within() 。如within(com.service.*)、within(com.service..*.*dao+)
2、
.* 表示包下的所有类
..*表示当前包下和子孙包下的所有类
逻辑运算符
访问连接点信息
AspectJ使用JoinPoint接口表示目标类连接点对象。如果是环绕增强,使用ProceedingJoinPoint表示连接点对象。
任何增强方法都可以将第一个入参声明为JoinPoint访问连接点上下文信息。
//
Method method = ((MethodSignature) pjp.getSignature()).getMethod();
WorkFlow workFlow = method.getAnnotation(WorkFlow.class);
Object args[] = pjp.getArgs();
绑定连接点方法入参 :实现匹配切点和绑定参数的双重功能
绑定类注解对象
绑定返回值
在后置增强中,可以通过returning绑定连接点方法的返回值 1和2名字必须相同,且2的类型必须和连接点的返回值类型匹配
绑定抛出的异常
1和2的名字要相同,且这个异常增强只在连接点抛出instanceof illegalargumentexception时才匹配
增强织入的顺序