在之前的读书笔记Spring in Acton 4读书笔记之AOP原理及Spring对AOP的支持中,讲解了AOP的各个组成部分,其中pointcut和advice组成了aspect,是AOP的基础。本文对应Spring in Action(Spring 实战)第四版的第四章第二节(4.2 Selecting join points with pointcuts)的内容,将讲解aspect特别是pointcut的语法。
Spring中的表达式主要使用AspectJ的表达式,另外,添加了一个自己的bean()函数。
AspectJ的语法
Spring的AOP中,pointcut使用AspectJ的一部分pointcut语法表达式,可使用的表达式如下:
- args(),匹配的函数,其参数的类型必须是args()指定的类型
- @args(),匹配的函数,其参数必须被@args指定的标签标注
- execution(),匹配指定的函数
- this(),匹配的函数,它的AOP代理实例必须是指定的类型
- target(),匹配的函数,所在类必须是指定的类型
- @target(),匹配的函数,所在类必须由指定类型的标签标注
- within(),匹配的函数,所在类必须是指定的类型之一
- @within(),匹配的函数,所在类必须由指定类型之一的标签标注(使用Spring AOP时,定义的方法必须在由指定类型之一的标签标注的类中)
- @annotation,匹配的函数,其自身必须由指定的标签标注。
如果尝试使用AspectJ的其它语法,Spring会抛出IllegalArgumentException异常。
上面的这些表达式中,实际上,只有execution是真正实行匹配的,其它的是进行进一步限制。
下面举例说明execution的使用。
可以看到,这里指定了方法为concert.Performance.perform,既指定了类,也指定了方法。这个例子中,“..”表示参数没有进行限制,”*”表示返回类型也没有进行限制。
1 | execution(* concert.Performance.perform(..)) |
execution和within方法使用&&进行关联,表示”与“,即两个条件都要满足,此外,可以使用||表示或,!表示非。也可以使用”and”,”or”和”not”。注:书中的例子有笔误,最后面多了一个多余的括号,我这里把它去掉了。
Spring添加的bean函数
Spring添加了bean()函数,声明join point必须是指定id的bean,例子如下:
1 | execution(* concert.Performance.perform()) |
表示只能作用在id为woodstock的bean的perform方法上。而下面的这个例子表示作用在id不是woodstock的bean的perform方法上。
1 | execution(* concert.Performance.perform()) |