8.4.5 基于注解的 零配置 方式 9. 切入点指示符

8.4.5 基于注解的 零配置 方式 9. 切入点指示符

前面定义切入点表达式时大量使用了execution表达式,其中**execution就是一个切入点指示符**,Spring AOP仅支持部分AspectJ的切入点指示符,但Spring AOP还额外支持一个bean切入点指示符。
不仅如此,因为Spring AOP只支持使用方法调用作为连接点,所以**Spring AOP的切入点指示符仅匹配方法执行的连接点**。
完整的AspectJ切入点语言支持大量的切入点指示符,但是Spring并不支持它们。Spring AOP不支持的切入点指示符有call, getsetpreinitializationstaticinitializationinitializationhandleradviceexecutionwithincodecflowcflowbelowif@thiswithincode。一旦在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
2
3
4
5
6
7
8
//匹配任意public方法的执行
execution(public * * (..))
//匹配任何方法名以"set"开始的方法的执行
execution(* set* (..))
//匹配AccountServicelmpI中任意方法的执行
execution(* org.crazyit.app.service.Impl.AccountServiceImpl.* (..))
//匹配org.crazyit.app.service.Impl包中任意类的任意方法的执行
execution(* org.crazyit.app.service.Impl.*.*(..))

within切入点指示符

within:用于限定匹配特定类型的连接点,当使用Spring AOP的时候,只能匹配方法执行的连接点。
例如,如下几个within表达式:

1
2
3
4
// 在org.crazyit.app.service包中的任意连接点(在 Spring AOP中只是方法执行的连接点)
within(org.crazyit.app.service.*)
// 在org.crazyit.app.service包或其子包中的任意连接点(在 Spring AOP中只是方法执行的连接点)
within(org.crazyit.app.service..*)

this切入点指示符

this:用于限定AOP代理必须是指定类型的实例,匹配该对象的所有连接点。当使用Spring AOP的时候,只能匹配方法执行的连接点。
例如,如下this表达式:

1
2
//匹配实现了org.crazyit.app.service.AccountService接口的AOP代理的所有连接点(在Spring AOP中只是方法执行的连接点)
this(org.crazyit.app.service.AccountService)

target切入点指示符

target:用于限定目标对象必须是指定类型的实例,匹配该对象的所有连接点。当使用Spring AOP的时候,只能匹配方法执行的连接点。
例如,如下target表达式

1
2
//匹配实现了`org.crazyit.app.service.AccountService`接口的目标对象的所有连接点
target(org.crazyit.app.service.AccountService)

args切入点指示符

args:用于对连接点的参数类型进行限制,要求参数类型是指定类型的实例。当使用Spring AOP的时候,只能匹配方法执行的连接点

1
2
//匹配只接受一个参数,且传入的参数类型是`Serializable`的所有连接点
args(java.io.Serializable)

该示例中给出的切入点表达式与execution(* * (java.io.Serializable)不同:

  • args版本只匹配动态运行时传入的参数值是Serializable类型的情形;
  • execution版本则匹配方法签名只包含一个Serializable类型的形参的方法

bean切入点指示符

另外, Spring AOP还提供了一个名为bean的切入点指示符,它用于限制只匹配指定Bean实例的连接点。当然, Spring AOP中只能使用方法执行作为连接点。
bean:用于限定只匹配指定Bean实例内的连接点,实际上只能使用方法执行作为连接点。定义bean表达式时需要传入Beanidname,表示只匹配该Bean实例内的连接点。支持使用"*"通配符。
例如,如下几个bean表达式:

1
2
3
4
//匹配 tradeService这个Bean实例内方法执行的连接点
bean(tradeService)
//匹配名字以Service结尾的Bean实例内方法执行的连接点
bean(*Service)

bean切入点表示式是Spring AOP额外支持的

bean切入点表达式是Spring AOP额外支持的,并不是AspectJ所支持的切入点指示符。这个指示符对Spring框架来说非常实用:它可以明确指定为Spring的哪个Bean织入增强处理。