Spring AOP支持的AspectJ切入点指示符以下:java
execution:用于匹配方法执行的链接点;this
within:用于匹配指定类型内的方法执行;spa
this:用于匹配当前AOP代理对象类型的执行方法;注意是AOP代理对象的类型匹配,这样就可能包括引入接口也类型匹配;.net
target:用于匹配当前目标对象类型的执行方法;注意是目标对象的类型匹配,这样就不包括引入接口也类型匹配;代理
args:用于匹配当前执行的方法传入的参数为指定类型的执行方法;code
@within:用于匹配因此持有指定注解类型内的方法;对象
@target:用于匹配当前目标对象类型的执行方法,其中目标对象持有指定的注解;接口
@args:用于匹配当前执行的方法传入的参数持有指定注解的执行;ci
@annotation:用于匹配当前执行方法持有指定注解的方法;get
bean:Spring AOP扩展的,AspectJ没有对于指示符,用于匹配特定名称的Bean对象的执行方法;
reference pointcut:表示引用其余命名切入点,只有@ApectJ风格支持,Schema风格不支持。
AspectJ切入点支持的切入点指示符还有: call、get、set、preinitialization、staticinitialization、initialization、handler、adviceexecution、withincode、cflow、cflowbelow、if、@this、@withincode;但Spring AOP目前不支持这些指示符,使用这些指示符将抛出IllegalArgumentException异常。这些指示符Spring AOP可能会在之后进行扩展。
AspectJ类型匹配的通配符:
* :匹配任何数量字符;
.. :(两个点)匹配任何数量字符的重复,如在类型模式中匹配任何数量子包;而在方法参数模式中匹配任何数量参数。
+ :匹配指定类型的子类型;仅能做为后缀放在类型模式后边。
java.lang.String 匹配String类型;
java.*.String 匹配java包下的任何“一级子包”下的String类型;
如匹配java.lang.String,但不匹配java.lang.ss.String
java..* 匹配java包及任何子包下的任何类型;
如匹配java.lang.String、java.lang.annotation.Annotation
java.lang.*ing 匹配任何java.lang包下的以ing结尾的类型;
java.lang.Number+ 匹配java.lang包下的任何Number的自类型;
如匹配java.lang.Integer,也匹配java.math.BigInteger
获取通知参数的两种方式:
使用JoinPoint获取:Spring AOP提供使用org.aspectj.lang.JoinPoint类型获取链接点数据,任何通知方法的第一个参数均可以是JoinPoint(环绕通知是ProceedingJoinPoint,JoinPoint子类),固然第一个参数位置也能够是JoinPoint.StaticPart类型,这个只返回链接点的静态部分。
自动获取:经过切入点表达式能够将相应的参数自动传递给通知方法,在Spring AOP中,除了execution和bean指示符不能传递参数给通知方法,其余指示符均可以将匹配的相应参数或对象自动传递给通知方法。
多个通知想要在同一链接点执行,顺序怎么定?
Spring AOP使用AspectJ的优先级规则来肯定通知执行顺序。总共有两种状况:同一切面中通知执行顺序、不一样切面中的通知执行顺序。
同一切面中通知执行顺序:须要将通知重构到两个切面,而后定义切面的执行顺序。
不一样切面中的通知执行顺序:经过经过指定切面的优先级来控制通知的执行顺序,
在@Aspect的标注的类上加@Order(1),@Order(2),或在配置中<aop:aspect ... order="1"/>
Spring AOP经过代理模式实现,目前支持两种代理:JDK动态代理、CGLIB代理来建立AOP代理,Spring建议优先使用JDK动态代理。
不能通知final方法,由于final方法不能被覆盖(CGLIB经过生成子类来建立代理)。
会产生两次构造器调用,第一次是目标类的构造器调用,第二次是CGLIB生成的代理类的构造器调用。若是须要CGLIB代理方法,请确保两次构造器调用不影响应用。
Spring AOP默认首先使用JDK动态代理来代理目标对象,若是目标对象没有实现任何接口将使用CGLIB代理,若是须要强制使用CGLIB代理,请使用以下方式指定:
对于Schema风格配置切面使用以下方式来指定使用CGLIB代理:
<aop:config proxy-target-class="true"/>
若是使用@AspectJ风格使用以下方式来指定使用CGLIB代理:
<aop:aspectj-autoproxy proxy-target-class="true"/>