Spring AOP支持的AspectJ切入點指示符
Spring AOP支持的AspectJ切入點指示符如下:
指示符 | 含義 |
---|---|
execution | 用于匹配方法執(zhí)行的連接點啸驯; |
within | 用于匹配指定類型內(nèi)的方法執(zhí)行; |
this | 用于匹配當(dāng)前AOP代理對象類型的執(zhí)行方法;注意是AOP代理對象的類型匹配碘饼,這樣就可能包括引入接口也類型匹配厚柳; |
target | 用于匹配當(dāng)前目標(biāo)對象類型的執(zhí)行方法涡尘;注意是 目標(biāo)對象的類型匹配悔捶,這樣就不包括引入接口也類型匹配; |
args | 用于匹配當(dāng)前執(zhí)行的方法傳入的參數(shù)為指定類型的執(zhí)行方法炎功; |
@within | 用于匹配所以持有指定注解類型內(nèi)的方法枚冗; |
@target | 用于匹配當(dāng)前目標(biāo)對象類型的執(zhí)行方法蛇损,其中目標(biāo)對象持有指定的注解; |
@args | 用于匹配當(dāng)前執(zhí)行的方法傳入的參數(shù)持有指定注解的執(zhí)行淤齐; |
@annotation | 用于匹配當(dāng)前執(zhí)行方法持有指定注解的方法股囊; |
bean | Spring AOP擴展的,AspectJ沒有對于指示符更啄,用于匹配特定名稱的Bean對象的執(zhí)行方法; |
reference pointcut | 表示引用其他命名切入點内狗,只有@ApectJ風(fēng)格支持义锥,Schema風(fēng)格不支持。 |
類型匹配語法
首先讓我們來了解下AspectJ類型匹配的通配符:
*
:匹配任何數(shù)量字符赂鲤;
..
:匹配任何數(shù)量字符的重復(fù),如在類型模式中匹配任何數(shù)量子包数初;而在方法參數(shù)模式中匹配任何數(shù)量參數(shù)泡孩。
+
:匹配指定類型的子類型;僅能作為后綴放在類型模式后邊珍德。
例如:
樣例 | 說明 |
---|---|
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結(jié)尾的類型 |
java.lang.Number+ |
匹配java.lang 包下的任何Number 的自類型获列;如匹配java.lang.Integer ,也匹配java.math.BigInteger
|
接下來再看一下具體的匹配表達(dá)式類型吧:
-
匹配類:使用如下方式匹配
注解? 類的全限定名字
- 注解:可選迫悠,類型上持有的注解巩梢,如@Deprecated;
- 類的全限定名:必填鞠抑,可以是任何類全限定名忌警。 -
匹配方法執(zhí)行:使用如下方式匹配:
注解? 修飾符? 返回值類型 類型聲明?方法名(參數(shù)列表) 異常列表?
- 注解:可選,方法上持有的注解箕速,如@Deprecated礼烈;
- 修飾符:可選此熬,如public、protected犀忱;
- 返回值類型:必填阴汇,可以是任何類型模式;“”表示所有類型拐纱;
- 類型聲明:可選哥倔,可以是任何類型模式;
- 方法名:必填东抹,可以使用“”進行模式匹配沃测;
- 參數(shù)列表:“()”表示方法沒有任何參數(shù);“(..)”表示匹配接受任意個參數(shù)的方法馏谨,“(..,java.lang.String)”表示匹配接受java.lang.String類型的參數(shù)結(jié)束附迷,且其前邊可以接受有任意個參數(shù)的方法挟秤;“(java.lang.String,..)” 表示匹配接受java.lang.String類型的參數(shù)開始,且其后邊可以接受任意個參數(shù)的方法艘刚;“(*,java.lang.String)” 表示匹配接受java.lang.String類型的參數(shù)結(jié)束攀甚,且其前邊接受有一個任意類型參數(shù)的方法;
- 異常列表:可選炸庞,以“throws 異常全限定名列表”聲明荚斯,異常全限定名列表如有多個以“查牌,”分割纸颜,如throws java.lang.IllegalArgumentException, java.lang.ArrayIndexOutOfBoundsException绎橘。 匹配Bean名稱:可以使用Bean的id或name進行匹配,并且可使用通配符“*”
組合切入點表達(dá)式
AspectJ使用 且(&&)涮较、或(||)冈止、非(!)來組合切入點表達(dá)式苫亦。
切入點使用示例
-
execution:使用“
execution(方法表達(dá)式)
”匹配方法執(zhí)行模式 描述 public * *(..)
任何公共方法的執(zhí)行 * com.learn..IHelloService.*()
com.learn包及所有子包下IHelloService接口中的任何無參方法 * com.learn..*.*(..)
com.learn包及所有子包下任何類的任何方法 * com.learn..IHelloService.*(*)
com.learn包及所有子包下IHelloService接口的任何只有一個參數(shù)方法 * (!com.learn..IHelloService+).*(..)
非“com.learn包及所有子包下IHelloService接口及子類型”的任何方法 * com.learn..IHelloService+.*()
com.learn包及所有子包下IHelloService接口及子類型的的任何無參方法 * com.learn..IHelloService*.test*(java.util.Date)
com.learn包及所有子包下IHelloService前綴類型的的以test開頭的只有一個參數(shù)類型為java.util.Date的方法屋剑,注意該匹配是根據(jù)方法簽名的參數(shù)類型進行匹配的诗眨,而不是根據(jù)執(zhí)行時傳入的參數(shù)類型決定的,如定義方法:public void test(Object obj);即使執(zhí)行時傳入java.util.Date巍膘,也不會匹配的芋簿; * com.learn..IHelloService.test(..) throws IllegalArgumentException, ArrayIndexOutOfBoundsException com.learn包及所有子包下IHelloService前綴類型的的任何方法与斤,且拋出IllegalArgumentException和ArrayIndexOutOfBoundsException異常 * (com.learn..IHelloService+ && java.io.Serializable+).*(..) 任何實現(xiàn)了com.learn包及所有子包下 IHelloService接口和java.io.Serializable接口的類型的任何方法 @java.lang.Deprecated * *(..)
任何持有@java.lang.Deprecated注解的方法 @(java.lang.Deprecated || com.learn..Secure) * *(..) 任何持有@java.lang.Deprecated或@com.learn..Secure注解的方法 (@com.learn..Secure *) *(..)
任何返回值類型持有@com.learn..Secure的方法 * (@com.learn..Secure *).*(..)
任何定義方法的類型持有@com.learn..Secure的方法 * *(@com.learn..Secure (*) , @com.learn..Secure (*))
任何簽名帶有兩個參數(shù)的方法,且這個兩個參數(shù)都被@Secure標(biāo)記了磷支,如public void test(@Secure String str1, @Secure String str1) * *((@ com.learn..Secure *))或 * *(@ com.learn..Secure *) 任何帶有一個參數(shù)的方法雾狈,且該參數(shù)類型持有@com.learn..Secure抵皱;如public void test(Model model);且Model類上持有@Secure注解 * *( @com.learn..Secure (@com.learn..Secure *) , @ com.learn..Secure (@com.learn..Secure *)) 任何帶有兩個參數(shù)的方法辩蛋,且這兩個參數(shù)都被@com.learn..Secure標(biāo)記了锭弊;且這兩個參數(shù)的類型上都持有@ com.learn..Secure味滞; * *( java.util.Map<com.learn..Model, com.learn..Model> , ..) 任何帶有一個java.util.Map參數(shù)的方法钮呀,且該參數(shù)類型是以< com.learn..Model, com.learn..Model >為泛型參數(shù);注意只匹配第一個參數(shù)為java.util.Map,不包括子類型蚁署;如public void test(HashMap<Model, Model> map, String str);將不匹配蚂四,必須使用“* *( java.util.HashMap<com.learn..Model,com.learn..Model> , ..)”進行匹配; 而public void test(Map map, int i);也將不匹配久妆,因為泛型參數(shù)不匹配 * *(java.util.Collection<@com.learn..Secure *>) 任何帶有一個參數(shù)(類型為java.util.Collection)的方法全度,且該參數(shù)類型是有一個泛型參數(shù),該泛型參數(shù)類型上持有@com.learn..Secure注解; 如public void test(Collection<Model> collection);Model類型上持有@com.learn..Secure * *(java.util.Set<? extends HashMap>) 任何帶有一個參數(shù)的方法蜕乡,且傳入的參數(shù)類型是有一個泛型參數(shù)层玲,該泛型參數(shù)類型繼承與HashMap; Spring AOP目前測試不能正常工作 * *(java.util.List<? super HashMap>)
任何帶有一個參數(shù)的方法扣癣,且傳入的參數(shù)類型是有一個泛型參數(shù)憨降,該泛型參數(shù)類型是HashMap的基類型;如public voi test(Map map)士嚎;Spring AOP目前測試不能正常工作 * *(*<@com.learn..Secure *>)
任何帶有一個參數(shù)的方法,且該參數(shù)類型是有一個泛型參數(shù)爵嗅,該泛型參數(shù)類型上持有@com.learn..Secure注解笨蚁;Spring AOP目前測試不能正常工作
-
within:使用“within(類型表達(dá)式)”匹配指定類型內(nèi)的方法執(zhí)行括细;
模式 描述 within(com.learn..*)
com.learn包及子包下的任何方法執(zhí)行 within(com.learn..IHelloService+)
com.learn包或所有子包下IHelloService類型及子類型的任何方法 within(@com.learn..Secure *)
持有com.learn..Secure注解的任何類型的任何方法,必須是在目標(biāo)對象上聲明這個注解锉试,在接口上聲明的對它不起作用
-
模式 描述 this(com.learn.model.Member)
當(dāng)前AOP對象實現(xiàn)了Member接口/抽象類的某些方法览濒,Member的父類未重載的方法不會被處理 this:使用“this(類型全限定名)”匹配當(dāng)前AOP代理對象類型的執(zhí)行方法应又;注意 是AOP代理對象的類型匹配丁频,這樣就可能包括引入接口方法也可以匹配邑贴;注意this中使用的表達(dá)式必須是類型全限定名,不支持通配符
模式 描述 this(com.learn.model.Member)
當(dāng)前AOP對象實現(xiàn)了Member接口/抽象類的某些方法奖磁,Member的父類未重載的方法不會被處理 -
target:使用“target(類型全限定名)”匹配當(dāng)前目標(biāo)對象類型的執(zhí)行方法繁疤;注意 是目標(biāo)對象的類型匹配稠腊,這樣就不包括引入接口也類型匹配;注意target中使用的表達(dá)式必須是類型全限定名架忌,不支持通配符
模式 描述 target(com.learn.model.Member)
當(dāng)前目標(biāo)對象(非AOP對象)實現(xiàn)了Member接口/抽象類的某些方法,Member的父類未重載的方法也會被處理 -
args:使用“args(參數(shù)類型列表)”匹配當(dāng)前執(zhí)行的方法傳入的參數(shù)為指定類型的執(zhí)行方法挠羔;注意是匹配傳入的參數(shù)類型埋嵌,不是匹配方法簽名的參數(shù)類型;參數(shù)類型列表中的參數(shù)必須是類型全限定名范舀,通配符不支持俐银;args屬于動態(tài)切入點端仰,這種切入點開銷非常大荔烧,非特殊情況最好不要使用
模式 描述 args (com.learn.model.Member,..)
任何一個以接受“傳入?yún)?shù)類型為 com.learn.model.Member
” 開頭,且其后可跟任意個任意類型的參數(shù)的方法執(zhí)行踊餐,args指定的參數(shù)類型是在運行時動態(tài)匹配的 -
@within:使用“@within(注解類型)”匹配所有持有指定注解類型內(nèi)的方法臀稚;注解類型也必須是全限定類型名
模式 描述 @within(com.learn.annotation.Secure)
任何目標(biāo)對象對應(yīng)的類型持有Secure注解的類方法吧寺; 必須是在目標(biāo)對象上聲明這個注解, 在接口上聲明的對它不起作用 -
@target:使用“@target(注解類型)”匹配當(dāng)前目標(biāo)對象類型的執(zhí)行方法幕帆,其中目標(biāo)對象持有指定的注解赖条;注解類型也必須是全限定類型名
模式 描述 @target(com.learn.annotation.Secure)
任何目標(biāo)對象持有Secure注解的類方法; 必須是在目標(biāo)對象上聲明這個注解碱茁,在接口上聲明的對它不起作用 -
@args:使用“@args(注解列表)”匹配當(dāng)前執(zhí)行的方法傳入的參數(shù)持有指定注解的執(zhí)行仿贬;注解類型也必須是全限定類型名
模式 描述 @args(com.learn.annotation.Secure)
任何一個只接受一個參數(shù)的方法诅蝶,且方法運行時傳入的參數(shù)持有注解 com.learn.annotation.Secure
募壕;動態(tài)切入點语盈,類似于arg指示符 -
@annotation:使用“@annotation(注解類型)”匹配當(dāng)前執(zhí)行方法持有指定注解的方法刀荒;注解類型也必須是全限定類型名;
模式 描述 @annotation(com.learn.annotation.Secure)
當(dāng)前執(zhí)行方法上持有注解 com.learn.annotation.Secure
將被匹配 -
bean:使用“bean(Bean id或名字通配符)”匹配特定名稱的Bean對象的執(zhí)行方法干毅;Spring ASP擴展的泼返,在AspectJ中無相應(yīng)概念;
模式 描述 bean(*Service)
匹配所有以Service命名(id或name)結(jié)尾的Bean reference pointcut: 表示引用其他命名切入點渠鸽, 只有@ApectJ風(fēng)格支持徽缚,Schema風(fēng)格不支持革屠,如下所示:
比如我們定義如下切面:
@Aspect
public class HelloServiceAspect {
//匹配com.learn.service.impl包及其子包下的所有類的所有方法
@Pointcut("execution(* com.learn.service.impl..*.*(..))")
public void executeService(){ }
}
可以通過如下方式引用:
@Aspect
@Component
public class HelloServiceExecutor {
@Before("com.learn.aop.HelloServiceAspect.executeService()")
public void doBeforeAdvice(){
System.out.println("我是前置通知!!!");
}
}
到此我們切入點表達(dá)式語法示例就介紹完了似芝,我們這些示例幾乎包含了日常開發(fā)中的所有情況,但當(dāng)然還有更復(fù)雜的語法等等吧恃,如果以上介紹的不能滿足您的需要麻诀,請參考AspectJ文檔。