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"/>  

相關文章
相關標籤/搜索