spring AspectJ的Execution表示式-備忘筆記(轉)
Aspectj切入點語法定義
在使用spring框架配置AOP的時候,不管是通過XML配置檔案還是註解的方式都需要定義pointcut"切入點"
例如定義切入點表示式 execution (* com.sample.service.impl..*.*(..))
execution()是最常用的切點函式,其語法如下所示:
整個表示式可以分為五個部分:
1、execution(): 表示式主體。
2、第一個*號:表示返回型別,*號表示所有的型別。
3、包名:表示需要攔截的包名,後面的兩個句點表示當前包和當前包的所有子包,com.sample.service.impl包、子孫包下所有類的方法。
4、第二個*號:表示類名,*號表示所有的類。
5、*(..):最後這個星號表示方法名,*號表示所有的方法,後面括弧裡面表示方法的引數,兩個句點表示任何引數。
AspectJ的Execution表示式
execution()
execution()是最常用的切點函式,其語法如下所示:
execution(<修飾符模式>? <返回型別模式> <方法名模式>(<引數模式>) <異常模式>?) 除了返回型別模式、方法名模式和引數模式外,其它項都是可選的。與其直接講解該方法的使用規則,還不如通過一個個具體的例子進行理解。下面,我們給出各種使用execution()函式例項。
1)通過方法簽名定義切點
execution(public * *(..))l
匹配所有目標類的public方法,但不匹配SmartSeller和protected void showGoods()方法。第一個*代表返回型別,第二個*代表方法名,而..代表任意入參的方法;
execution(* *To(..))l
匹配目標類所有以To為字尾的方法。它匹配NaiveWaiter和NaughtyWaiter的greetTo()和serveTo()方法。第一個*代表返回型別,而*To代表任意以To為字尾的方法;
2)通過類定義切點
execution(* com.baobaotao.Waiter.*(..))l
匹配Waiter介面的所有方法,它匹配NaiveWaiter和NaughtyWaiter類的greetTo()和serveTo()方法。第一個*代表返回任意型別,com.baobaotao.Waiter.*代表Waiter介面中的所有方法;
execution(* com.baobaotao.Waiter+.*(..))l
匹 配Waiter介面及其所有實現類的方法,它不但匹配NaiveWaiter和NaughtyWaiter類的greetTo()和serveTo()這 兩個Waiter介面定義的方法,同時還匹配NaiveWaiter#smile()和NaughtyWaiter#joke()這兩個不在Waiter 介面中定義的方法。
3)通過類包定義切點
在類名模式串中,“.*”表示包下的所有類,而“..*”表示包、子孫包下的所有類。
execution(* com.baobaotao.*(..))l
匹配com.baobaotao包下所有類的所有方法;
execution(* com.baobaotao..*(..))l
匹 配com.baobaotao包、子孫包下所有類的所有方法,如com.baobaotao.dao,com.baobaotao.servier以及 com.baobaotao.dao.user包下的所有類的所有方法都匹配。“..”出現在類名中時,後面必須跟“*”,表示包、子孫包下的所有類;
execution(* com..*.*Dao.find*(..))l
匹配包名字首為com的任何包下類名字尾為Dao的方法,方法名必須以find為字首。如com.baobaotao.UserDao#findByUserId()、com.baobaotao.dao.ForumDao#findById()的方法都匹配切點。
4)通過方法入參定義切點
切點表示式中方法入參部分比較複雜,可以使用“*”和“ ..”萬用字元,其中“*”表示任意型別的引數,而“..”表示任意型別引數且引數個數不限。
execution(* joke(String,int)))l
匹 配joke(String,int)方法,且joke()方法的第一個入參是String,第二個入參是int。它匹配 NaughtyWaiter#joke(String,int)方法。如果方法中的入參型別是java.lang包下的類,可以直接使用類名,否則必須使用全限定類名,如joke(java.util.List,int);
execution(* joke(String,*)))l
匹 配目標類中的joke()方法,該方法第一個入參為String,第二個入參可以是任意型別,如joke(String s1,String s2)和joke(String s1,double d2)都匹配,但joke(String s1,double d2,String s3)則不匹配;
execution(* joke(String,..)))l
匹配目標類中的joke()方法,該方法第 一個入參為String,後面可以有任意個入參且入參型別不限,如joke(String s1)、joke(String s1,String s2)和joke(String s1,double d2,String s3)都匹配。
execution(* joke(Object+)))l
匹 配目標類中的joke()方法,方法擁有一個入參,且入參是Object型別或該類的子類。它匹配joke(String s1)和joke(Client c)。如果我們定義的切點是execution(* joke(Object)),則只匹配joke(Object object)而不匹配joke(String cc)或joke(Client c)。
args()和@args()
args()函式的入參是類名,@args()函式的入參必須是註解類的類名。雖然args()允許在類名後使用+萬用字元字尾,但該萬用字元在此處沒有意義:新增和不新增效果都一樣。
1)args()
該函式接受一個類名,表示目標類方法入參物件按型別匹配於指定類時,切點匹配,如下面的例子:
args(com.baobaotao.Waiter)
表 示執行時入參是Waiter型別的方法,它和execution(* *(com.baobaotao.Waiter))區別在於後者是針對類方法的簽名而言的,而前者則針對執行時的入參型別而言。如 args(com.baobaotao.Waiter)既匹配於addWaiter(Waiter waiter),也匹配於addNaiveWaiter(NaiveWaiter naiveWaiter),而execution(* *(com.baobaotao.Waiter))只匹配addWaiter(Waiter waiter)方法;實際上,args(com.baobaotao.Waiter)等價於execution(* *(com.baobaotao.Waiter+)),當然也等價於args(com.baobaotao.Waiter+)。
2)@args()
該函式接受一個註解類的類名,當方法的執行時入參物件標註髮指定的註解時,方法匹配切點。這個切點函式的匹配規則不太容易理解,我們通過以下示意圖對此進行詳細講解:
類別 |
函式 |
入參 |
說明 |
方法切點函式 |
execution() |
方法 匹配模式串 |
表示滿足某一匹配模式的所有目標類方法連線點。如execution(* greetTo(..))表示所有目標類中的greetTo()方法。 |
@annotation() |
方法注 解類名 |
表示標註了特定註解的目標方法連線點。如@annotation(com.baobaotao.anno.NeedTest)表示任何標註了@NeedTest註解的目標類方法。 |
|
方法入參切點函式 |
args() |
類名 |
通過判別目標類方法執行時入參物件的型別定義指定連線點。如args(com.baobaotao.Waiter)表示所有有且僅有一個按型別匹配於Waiter的入參的方法。 |
@args() |
型別注 解類名 |
通過判別目標方法的執行時入參物件的類是否標註特定註解來指定連線點。如@args(com.baobaotao.Monitorable)表示任何這樣的一個目標方法:它有一個入參且入參物件的類標註@Monitorable註解。 |
|
目標類切點函式 |
within() |
類名匹配串 |
表示特定域下的所有連線點。如within(com.baobaotao.service.*)表示com.baobaotao.service包中的所有連線點,也即包中所有類的所有方法,而within(com.baobaotao.service.*Service)表示在com.baobaotao.service包中,所有以Service結尾的類的所有連線點。 |
target() |
類名 |
假如目標類按型別匹配於指定類,則目標類的所有連線點匹配這個切點。如通過target(com.baobaotao.Waiter)定義的切點,Waiter、以及Waiter實現類NaiveWaiter中所有連線點都匹配該切點。 |
|
@within() |
型別註解類名 |
假如目標類按型別匹配於某個類A,且類A標註了特定註解,則目標類的所有連線點匹配這個切點。 如@within(com.baobaotao.Monitorable)定義的切點,假如Waiter類標註了@Monitorable註解,則Waiter以及Waiter實現類NaiveWaiter類的所有連線點都匹配。 |
|
@target() |
型別註解類名 |
目標類標註了特定註解,則目標類所有連線點匹配該切點。如@target(com.baobaotao.Monitorable),假如NaiveWaiter標註了@Monitorable,則NaiveWaiter所有連線點匹配切點。 |
|
代理類切點函式 |
this() |
類名 |
代理類按型別匹配於指定類,則被代理的目標類所有連線點匹配切點。這個函式比較難理解,這裡暫不舉例,留待後面詳解。 |