8.4.5 基于注解的 零配置 方式 9. 切入点指示符
前面定义切入点表达式时大量使用了execution
表达式,其中execution
就是一个切入点指示符,Spring AOP
仅支持部分AspectJ
的切入点指示符,但Spring AOP
还额外支持一个bean
切入点指示符。
不仅如此,因为Spring AOP
只支持使用方法调用作为连接点,所以Spring AOP
的切入点指示符仅匹配方法执行的连接点。
完整的AspectJ
切入点语言支持大量的切入点指示符,但是Spring
并不支持它们。Spring AOP
不支持的切入点指示符有call
, get
、set
、 preinitialization
、 staticinitialization
、initialization
、 handler
、 adviceexecution
、 withincode
、cflow
、 cflowbelow
、if
、@this
和withincode
。一旦在Spring AOP
中使用这些指示符,将会导致抛出llegalArgumentException
异常。
Spring AOP支持的切入点指示符
Spring AOP
一共支持如下几种切入点指示符。
execution切入点指示符
execution
:用于匹配执行方法的连接点,这是Spring AOP
中最主要的切入点指示符。该切入点的用法也相对复杂,
execution表达式的格式
execution
表达式的格式如下:execution(modifiers-pattern? ret-type-pattern declaring-type-pattern? name-pattern(param-pattern) throws-pattern?
上面格式中的execution
是不变的,用于作为execution
表达式的开头,整个表达式中各部分的解释如下。
表达式的各组成部分 | 描述 |
---|---|
modifiers-pattern |
指定方法的修饰符 ,支持通配符,该部分可省略。 |
ret-type-pattern |
指定方法的返回值类型 ,支持通配符,可以使用"*" 通配符来匹配所有的返回值类型。 |
declaring-type-pattern |
指定方法所属的类 ,支持通配符,该部分可省略。 |
name-pattern |
指定匹配指定的方法名 ,支持通配符,可以使用"*" 通配符来匹配所有方法。 |
param-pattern |
指定方法声明中的形参列表 . |
throws- pattern |
指定方法声明抛出的异常 ,支持通配符,该部分可省略 |
param-pattern支持的通配符
param-pattern
支持两个通配符,即"*"
和”..
“
其中"*"
代表个任意类型的参数,而"."
代表零个或多个任意类型的参数。
例如:
()
匹配了一个不接受任何参数的方法,(..)
匹配了一个接受任意数量参数的方法(零个或更多),(*)
匹配了一个接受个任何类型参数的方法,(*,String)
匹配了接受两个参数的方法,第一个可以是任意类型,第二个则必须是String
类型。
execution表示式示例
例如,如下几个execution
表达式:
1 | //匹配任意public方法的执行 |
within切入点指示符
within
:用于限定匹配特定类型的连接点,当使用Spring AOP
的时候,只能匹配方法执行的连接点。
例如,如下几个within
表达式:
1 | // 在org.crazyit.app.service包中的任意连接点(在 Spring AOP中只是方法执行的连接点) |
this切入点指示符
this
:用于限定AOP代理
必须是指定类型的实例,匹配该对象的所有连接点。当使用Spring AOP
的时候,只能匹配方法执行的连接点。
例如,如下this
表达式:
1 | //匹配实现了org.crazyit.app.service.AccountService接口的AOP代理的所有连接点(在Spring AOP中只是方法执行的连接点) |
target切入点指示符
target
:用于限定目标对象
必须是指定类型的实例,匹配该对象的所有连接点。当使用Spring AOP
的时候,只能匹配方法执行的连接点。
例如,如下target
表达式
1 | //匹配实现了`org.crazyit.app.service.AccountService`接口的目标对象的所有连接点 |
args切入点指示符
args
:用于对连接点的参数类型进行限制,要求参数类型是指定类型的实例。当使用Spring AOP
的时候,只能匹配方法执行的连接点
1 | //匹配只接受一个参数,且传入的参数类型是`Serializable`的所有连接点 |
该示例中给出的切入点表达式与execution(* * (java.io.Serializable)
不同:
args
版本只匹配动态运行时传入的参数值是Serializable
类型的情形;execution
版本则匹配方法签名只包含一个Serializable
类型的形参的方法
bean切入点指示符
另外, Spring AOP
还提供了一个名为bean
的切入点指示符,它用于限制只匹配指定Bean
实例的连接点。当然, Spring AOP
中只能使用方法执行作为连接点。bean
:用于限定只匹配指定Bean
实例内的连接点,实际上只能使用方法执行作为连接点。定义bean
表达式时需要传入Bean
的id
或name
,表示只匹配该Bean
实例内的连接点。支持使用"*"
通配符。
例如,如下几个bean
表达式:
1 | //匹配 tradeService这个Bean实例内方法执行的连接点 |
bean切入点表示式是Spring AOP额外支持的
bean
切入点表达式是Spring AOP
额外支持的,并不是AspectJ
所支持的切入点指示符。这个指示符对Spring
框架来说非常实用:它可以明确指定为Spring
的哪个Bean
织入增强处理。