為了能夠靈活定義切入點位置,Spring AOP提供了多種切入點指示符。
execution———用來匹配執行方法的連接點
語法結構: execution( 方法修飾符 方法返回值 方法所屬類 匹配方法名 ( 方法中的形參表 ) 方法申明拋出的異常 )
其中紅色字體的部分時不能省略的,各部分都支持通配符 “*” 來匹配全部。
比較特殊的為形參表部分,其支持兩種通配符
- "*":代表一個任意類型的參數;
- “..”:代表零個或多個任意類型的參數。
例如:
()匹配一個無參方法
(..)匹配一個可接受任意數量參數和類型的方法
(*)匹配一個接受一個任意類型參數的方法
(*,Integer)匹配一個接受兩個參數的方法,第一個可以為任意類型,第二個必須為Integer。
下面舉一些execution的使用實例:
分類 | 示例 | 描述 |
通過方法簽名定義切入點 | execution(public * * (..)) | 匹配所有目標類的public方法,第一個*為返回類型,第二個*為方法名 |
execution(* save* (..)) | 匹配所有目標類以save開頭的方法,第一個*代表返回類型 | |
execution(**product(*,String)) | 匹配目標類所有以product結尾的方法,並且其方法的參數表第一個參數可為任意類型,第二個參數必須為String | |
通過類定義切入點 | execution(* aop_part.Demo1.service.*(..)) | 匹配service接口及其實現子類中的所有方法 |
通過包定義切入點 | execution(* aop_part.*(..)) | 匹配aop_part包下的所有類的所有方法,但不包括子包 |
execution(* aop_part..*(..)) | 匹配aop_part包下的所有類的所有方法,包括子包。(當".."出現再類名中時,后面必須跟“*”,表示包、子孫包下的所有類) | |
execution(* aop_part..*.*service.find*(..)) | 匹配aop_part包及其子包下的所有后綴名為service的類中,所有方法名必須以find為前綴的方法 | |
通過方法形參定義切入點 | execution(*foo(String,int)) | 匹配所有方法名為foo,且有兩個參數,其中,第一個的類型為String,第二個的類型為int |
execution(* foo(String,..)) | 匹配所有方法名為foo,且至少含有一個參數,並且第一個參數為String的方法(后面可以有任意個類型不限的形參) |
within————通過類匹配模式申明切入點(只能通過類型匹配連接點)
例如:within(aop_part..*) 表示匹配包aop_part以及子包的所有方法
由於execution可以匹配包、類、方法,而within只能匹配包、類,因此execution完全可以代替within的功能。
this————限定AOP代理必須時指定類型的實例,用於匹配該對象的所有連接點
例如:this(aop_part.service.GodService) 表示匹配了GodService接口的代理對象的所有連接點
target————通過判斷目標類的類型確定判斷的是否匹配
this通過判斷代理類的類型來決定是否和切入點匹配,兩者限定的對象都是指定類型的實例。
例如: target(aop_part.service.GodService) 表示匹配實現了GodService接口的目標對象的所有連接點
args————用於對連接點的參數類型進行限制,要求參數類型時指定類型的實例
例如:args(aop_part.service) 表示匹配時,出入的參數類型時service的方法
其與execution(**(aop_part.service))的區別為,execution針對的時方法簽名,而args針對的是運行時的實際參數類型。
例:
args既匹配buyGoods(service newService),也匹配buyGoods(Buyservice newService) <Buyservice為service的子類>
execution只匹配buyGoods(service newService)
組合切入點
支持 &&、 || 、!
與其他語言所代表的意思相同
例:args(aop_part.service) &&execution(**(aop_part.service))