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织入增强处理。