spring切面表達式詳解


舉例說明

如切點表達式 execution (* com.sample.service.impl..*.*(..))
execution()是最常用的切點函數,其語法如下所示:
整個表達式可以分為五個部分:
1、execution(): 表達式主體。
2、第一個*號:表示返回類型,*號表示所有的類型。
3、包名:表示需要攔截的包名,后面的兩個句點表示當前包和當前包的所有子包,com.sample.service.impl包、子孫包下所有類的方法。
4、第二個*號:表示類名,*號表示所有的類。
5、*(..):最后這個星號表示方法名,*號表示所有的方法,后面括弧里面表示方法的參數,兩個句點表示任何參數。

1)通過方法簽名定義切點

execution(public * *(..))
匹配所有目標類的public方法,但不匹配SmartSeller和protected void showGoods()方法。第一個*代表返回類型,第二個*代表方法名,而..代表任意入參的方法;
execution(* *To(..))
匹配目標類所有以To為后綴的方法。它匹配NaiveWaiter和NaughtyWaiter的greetTo()和serveTo()方法。第一個*代表返回類型,而*To代表任意以To為后綴的方法;

2)通過類定義切點

execution(* com.baobaotao.Waiter.*(..))
匹配Waiter接口的所有方法,它匹配NaiveWaiter和NaughtyWaiter類的greetTo()和serveTo()方法。第一個*代表返回任意類型,com.baobaotao.Waiter.*代表Waiter接口中的所有方法;
execution(* com.baobaotao.Waiter+.*(..)) (+表示包括當前類和子類子孫類)
匹配Waiter接口及其子接口及其所有實現類的方法,它不但匹配NaiveWaiter和NaughtyWaiter類的greetTo()和serveTo()這 兩個Waiter接口定義的方法,同時還匹配Waiter子類子孫類下的方法

3)通過類包定義切點

在類名模式串中,“.*”表示包下的所有類,而“..*”表示包、子孫包下的所有類。
execution(* com.baobaotao.*(..))
匹配com.baobaotao包下所有類的所有方法;
execution(* com.baobaotao..*(..))
匹 配com.baobaotao包、子孫包下所有類的所有方法,如com.baobaotao.dao,com.baobaotao.servier以及 com.baobaotao.dao.user包下的所有類的所有方法都匹配。“..”出現在類名中時,后面必須跟“*”,表示包、子孫包下的所有類;
execution(* com..*.*Dao.find*(..))
匹配包名前綴為com的任何包下類名后綴為Dao的方法,方法名必須以find為前綴。如com.baobaotao.UserDao#findByUserId()、com.baobaotao.dao.ForumDao#findById()的方法都匹配切點。

4)通過方法入參定義切點

切點表達式中方法入參部分比較復雜,使用“*”和“ ..”通配符,其中“*”表示任意類型的參數,而“..”表示任意類型參數且參數個數不限。
execution(* joke(String,int)))
匹 配joke(String,int)方法,且joke()方法的第一個入參是String,第二個入參是int。它匹配 NaughtyWaiter#joke(String,int)方法。如果方法中的入參類型是java.lang包下的類,可以直接使用類名,否則必須使用全限定類名,如joke(java.util.List,int);
execution(* joke(String,*)))
匹 配目標類中的joke()方法,該方法第一個入參為String,第二個入參可以是任意類型,如joke(String s1,String s2)和joke(String s1,double d2)都匹配,但joke(String s1,double d2,String s3)則不匹配;
execution(* joke(String,..)))
匹配目標類中的joke()方法,該方法第 一個入參為String,后面可以有任意個入參且入參類型不限,如joke(String s1)、joke(String s1,String s2)和joke(String s1,double d2,String s3)都匹配。
execution(* joke(Object+)))
匹 配目標類中的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()

類名

 代理類按類型匹配於指定類,則被代理的目標類所有連接點匹配切點。這個函數比較難理解,這里暫不舉例,留待后面詳解。

 

within(com.example.demo.interceptor.*) interceptor包下所有類方法執行都會進切面

within(@com.example.demo.interceptor.TestAno *) 標有TestAno注解的類下的方法執行時都會經過切面

 

target入參為全限定類名 實際作用同this,區別在於this匹配aop代理對象,target匹配目標對象

target(com.example.demo.interceptor.TestService) TestService接口及其子接口實現類執行時都會進入切面

target(com.example.demo.interceptor.ChildTestServiceImpl) ChildTestServiceImpl類方法執行時進入切面

 

@within入參為注解全限定類名

@within(com.example.demo.interceptor.TestAno) 標有注解TestAno的類會進入切面(注意注解只能在實現類中,不能標注接口)

 

this入參為全限定類名

this(com.example.demo.interceptor.TestService) TestService接口及其子接口實現類執行時都會進入切面

this(com.example.demo.interceptor.ChildTestServiceImpl) ChildTestServiceImpl類方法執行時進入切面

 

小驚喜 

 1、積少成多,下載高佣聯盟,領取各大平台隱藏優惠券,每次購物省個幾十塊錢不香嗎。

使用方法:復制商品鏈接打開高佣聯盟自動彈出優惠券,點擊跳轉到對應平台app內領券購買,或者直接高佣聯盟內搜索有優惠券商品點擊跳轉到淘寶等平台領券購買。

通過下方二維碼注冊的用戶可添加微信liershuang123(微信號)領取價值千元海量學習視頻。

為表誠意奉獻部分資料:

軟件電子書:鏈接:https://pan.baidu.com/s/1_cUtPtZZbtYTF7C_jwtxwQ 提取碼:8ayn
架構師二期:鏈接:https://pan.baidu.com/s/1yMhDFVeGpTO8KTuRRL4ZsA 提取碼:ui5v
架構師階段課程:鏈接:https://pan.baidu.com/s/16xf1qVhoxQJVT_jL73gc3A 提取碼:2k6j

          

 2、本人重金購買付費前后端分離腳手架源碼一套,現10元出售,加微信liershuang123獲取源碼

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM