springboot aop的execution 表達式詳解

Aspectj切入點語法定義java

 

在使用spring框架配置AOP的時候,無論是經過XML配置文件仍是註解的方式都須要定義pointcut"切入點"spring

例如定義切入點表達式  execution (* com.sample.service.impl..*.*(..))框架

execution()是最經常使用的切點函數,其語法以下所示:函數

 整個表達式能夠分爲五個部分:this

 一、execution(): 表達式主體。代理

 二、第一個*號:表示返回類型,*號表示全部的類型。對象

 三、包名:表示須要攔截的包名,後面的兩個句點表示當前包和當前包的全部子包,com.sample.service.impl包、子孫包下全部類的方法。blog

 四、第二個*號:表示類名,*號表示全部的類。接口

 五、*(..):最後這個星號表示方法名,*號表示全部的方法,後面括弧裏面表示方法的參數,兩個句點表示任何參數。get

 

 

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()

類名

 代理類按類型匹配於指定類,則被代理的目標類全部鏈接點匹配切點。這個函數比較難理解,這裏暫不舉例,留待後面詳解。


原文地址:http://zhuchengzzcc.iteye.com/blog/1504014

相關文章
相關標籤/搜索