AspectJ 一些該了解的概念
AspectJ就是AOP,只不過是面向java的嚎莉。AOP里面有一些重要基本的概念
什么是AOP
AOP是Aspect Oriented Programming的縮寫,即『面向切面編程』动壤。它和我們平時接觸到的OOP都是編程的不同思想萝喘,OOP,即『面向?qū)ο缶幊獭磺戆茫岢氖菍⒐δ苣K化阁簸,對象化,而AOP的思想哼丈,則不太一樣启妹,它提倡的是針對同一類問題的統(tǒng)一處理,當(dāng)然醉旦,我們在實際編程過程中饶米,不可能單純的安裝AOP或者OOP的思想來編程桨啃,很多時候,可能會混合多種編程思想檬输,大家也不必要糾結(jié)該使用哪種思想照瘾,取百家之長,才是正道丧慈。
那么AOP這種編程思想有什么用呢析命,一般來說粘我,主要用于不想侵入原有代碼的場景中蔫缸,例如SDK需要無侵入的在宿主中插入一些代碼存璃,做日志埋點距境、性能監(jiān)控、動態(tài)權(quán)限控制赔嚎、甚至是代碼調(diào)試等等现喳。
Aspect (切面)
實現(xiàn)了cross-cutting功能怔接,是針對切面的模塊吟税。最常見的是logging模塊凹耙、方法執(zhí)行耗時模塊,這樣乌妙,程序按功能被分為好幾層使兔,如果按傳統(tǒng)的繼承的話,商業(yè)模型繼承日志模塊的話需要插入修改的地方太多藤韵,而通過創(chuàng)建一個切面就可以使用AOP來實現(xiàn)相同的功能了,我們可以針對不同的需求做出不同的切面熊经。
jointpoint(連接點)
連接點是切面插入應(yīng)用程序的地方泽艘,該點能被方法調(diào)用,而且也會被拋出意外镐依。連接點是應(yīng)用程序提供給切面插入的地方匹涮,在插入地建立AspectJ程序與源程序的連接。例如槐壳,構(gòu)造方法調(diào)用然低、調(diào)用方法、方法執(zhí)行务唐、異常等等雳攘,這些都是Join Points,實際上枫笛,也就是你想把新的代碼插在程序的哪個地方吨灭,是插在構(gòu)造方法中,還是插在某個方法調(diào)用前刑巧,或者是插在某個方法中喧兄,這個地方就是Join Points
pointcut(切點)
pointcut可以控制你把哪些advice應(yīng)用于jointpoint上去无畔,通常你使用pointcuts通過正則表達式來把明顯的名字和模式進行匹配應(yīng)用。決定了那個jointpoint會獲得通知吠冤。分為call浑彰、execution、target拯辙、this闸昨、within等關(guān)鍵字。與joinPoint相比薄风,pointcut就是一個具體的切點(需要插入代碼的地方)
advice(處理邏輯)
advice是我們切面功能的實現(xiàn)饵较,它是切點的真正執(zhí)行的地方。比如像寫日志到一個文件中遭赂,advice(包括:before循诉、after、around等)在jointpoint處插入代碼到應(yīng)用程序中撇他。我們來看一看原AspectJ程序和反編譯過后的程序茄猫。看完下面的圖我們就大概明白了AspectJ是如何達到監(jiān)控源程序的信息了困肩。
舉個例子
@Before("execution(* android.app.Activity.on**(..))")
public void onActivityMethodBefore(JoinPoint joinPoint) throws Throwable {
}
- @Before 這是一個advice
- execution 這是一個Join Point
- (* android.app.Activity.on**(..)" 這是一個正則表達式
- 第一個*表示返回值(任意類型) - 方法的路徑(通過正則匹配) - ()表示方法的參數(shù)划纽,可以指定類型
- onActivityMethodBefore 表示切入點的方法
Method 參數(shù)規(guī)則
表達式 | 含義 |
---|---|
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 |
參數(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ù)的方法 |