Spring AOP 2

AspectJ切入点语法

Spring AOP支持的AspectJ切入点指示符以下:java

         execution用于匹配方法执行的链接点;this

         within用于匹配指定类型内的方法执行;spa

         this用于匹配当前AOP代理对象类型的执行方法;注意是AOP代理对象的类型匹配,这样就可能包括引入接口也类型匹配;.net

         target用于匹配当前目标对象类型的执行方法;注意是目标对象的类型匹配,这样就不包括引入接口也类型匹配;代理

         args用于匹配当前执行的方法传入的参数为指定类型的执行方法;code

         @within用于匹配因此持有指定注解类型内的方法对象

         @target用于匹配当前目标对象类型的执行方法,其中目标对象持有指定的注解;接口

         @args用于匹配当前执行的方法传入的参数持有指定注解的执行;ci

         @annotation用于匹配当前执行方法持有指定注解的方法;get

         beanSpring 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动态代理。

  • JDK动态代理:使用java.lang.reflect.Proxy动态代理实现,即提取目标对象的接口,而后对接口建立AOP代理。
  • CGLIB代理:CGLIB代理不只能进行接口代理,也能进行类代理,CGLIB代理须要注意如下问题:

       不能通知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"/>  

相关文章
相关标签/搜索