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