您好,登錄后才能下訂單哦!
直入主題,下面對(duì)AOP中幾個(gè)關(guān)鍵的術(shù)語(yǔ)進(jìn)行簡(jiǎn)單的說(shuō)明
連接點(diǎn)是對(duì)程序執(zhí)行過(guò)程中可被織入額外代碼的特定點(diǎn)的描述。連接點(diǎn)包含了兩個(gè)信息,一個(gè)是描述代碼中定義好的客觀存在事物的“位置”,例如某個(gè)類中的某個(gè)屬性、方法等。另一個(gè)是描述“位置”在執(zhí)行過(guò)程中的某個(gè)時(shí)刻,例如:屬性的初始化前、屬性的初始化后、方法執(zhí)行前、方法執(zhí)行后等。
如果我們用代碼來(lái)描述,則可以像下面這樣
//方位描述對(duì)象
class Location{
//某對(duì)象【作用的對(duì)象】
String className ;
//執(zhí)行點(diǎn)類型【屬性、方法等】
String type ;
//某執(zhí)行點(diǎn)名稱【對(duì)應(yīng)的屬性名、方法名等】
String name ;
//構(gòu)造方法
public Location(String className,String type,String name){}
}
//執(zhí)行點(diǎn)描述對(duì)象
class JoinPointDefined{
//方位
Location location ;
//執(zhí)行時(shí)間點(diǎn)
String execTimePoint ;
//構(gòu)造方法
public JoinPointDefined(Location location,String timePoint){}
}
class A{
String getName(){}
int getAge(){}
}
//執(zhí)行點(diǎn)1
JoinPointDefined joinpoint1 = new JoinPointDefined(new Location("com.A",“method”,"getName"),"before") ;
//執(zhí)行點(diǎn)2
JoinPointDefined joinpoint1 = new JoinPointDefined(new Location("com.A",“method”,"getName"),"after") ;
//執(zhí)行點(diǎn)3
JoinPointDefined joinpoint2 = new JoinPointDefined(new Location("com.A",“method”,"getAge),"after") ;
//執(zhí)行點(diǎn)N.....
對(duì)于不同的AOP實(shí)現(xiàn)框架,其能支持的連接點(diǎn)類型和運(yùn)行時(shí)時(shí)刻也不盡相同,例如Spring AOP框架支持對(duì)方法在執(zhí)行前、執(zhí)行后、執(zhí)行前后、拋出異常后等幾個(gè)時(shí)刻織入代碼。
以上面的類A為例,其中有兩個(gè)方法,假設(shè)Spring AOP框架只支持方法的執(zhí)行前、執(zhí)行后、拋出異常后的3個(gè)時(shí)刻,那么對(duì)Spring AOP而已其類A的執(zhí)行點(diǎn)有 2*3 = 6 個(gè) 。
在實(shí)際的代碼中,我們一般都需要明確的指定在哪些方法上織入我們額外的代碼,那么如何來(lái)描述呢, 于是便有了切點(diǎn)(Pointcut)
切點(diǎn)用于明確指定連接點(diǎn)中的“方位”,如具體的哪些類中的哪些方法。切點(diǎn)就像SQL中的where條件,其目的就是使用類和方法作為篩選條件在眾多的連接點(diǎn)中篩選出滿足條件的。在Spring AOP中,切點(diǎn)通過(guò)org.springframework.aop.Pointcut接口描述。
通過(guò)切點(diǎn)我們篩選出了滿足條件的類型和方法,但該方法對(duì)應(yīng)了多個(gè)連接點(diǎn),為了進(jìn)一步的刪選,我們還可以在篩選條件中加上“執(zhí)行時(shí)刻”的信息。
在Spring AOP框架中使用Advice(增強(qiáng))來(lái)描述“執(zhí)行時(shí)刻”的信息。
增強(qiáng)除了描述“執(zhí)行時(shí)刻”(方位)的信息外,同時(shí)還包含了我們?cè)谶B接點(diǎn)上要織入的程序代碼。
在Spring AOP中,每個(gè)增強(qiáng)接口都各自代表了其方位信息,如:BeforeAdvice、AfterReturningAdvice等。
切面由切點(diǎn)(Pointcut)和增強(qiáng)(Advice)組成,它既包括橫切邏輯的定義,也包括連接點(diǎn)的定義。Spring AOP框架根據(jù)切面的定義來(lái)實(shí)施AOP的工作??梢岳斫鉃榍忻婢褪菍?duì)切點(diǎn)和增強(qiáng)的引用。
Spring使用org.springframework.aop.Advisor接口表示切面的概念。在Spring AOP中切面分為 一般切面(Advisor)、切點(diǎn)切面(PointcutAdvisor)和引介切面(IntroductionAdvisor), 同時(shí),切面都繼承自Advice。
1)普通切面:僅包含一個(gè)Advice,它代表的橫切的連接點(diǎn)事所有目標(biāo)類的所有方法。
2)切點(diǎn)切面:具有切點(diǎn)的切面,包含Advice和Pontcut兩個(gè)類,這樣就可以通過(guò)類、方法名和方法方位等信息靈活的定義切面的連接點(diǎn)。
3)引介切面:它應(yīng)用與類層面上,引介切點(diǎn)使用ClassFilter進(jìn)行定義。
上面的“連接點(diǎn)”、“切點(diǎn)”和“增強(qiáng)”都是基于“類”在描述的,其定義的是某些類型中的某些方法上的某些預(yù)先定義的運(yùn)行時(shí)刻,可以說(shuō)他們都是靜態(tài)的描述信息。
但在程序的運(yùn)行過(guò)程中,每個(gè)被切面篩選出的類都可能會(huì)被實(shí)例化成多個(gè)實(shí)例,而各個(gè)實(shí)例就是這里的目標(biāo)對(duì)象,Spring AOP框架會(huì)在各個(gè)實(shí)例上運(yùn)行織入的代碼【可能運(yùn)行期動(dòng)態(tài)加入執(zhí)行邏輯,也可能編譯期直接織入到class文件中】。
就是將增強(qiáng)添加到目標(biāo)類型的具體連接點(diǎn)上的過(guò)程。其實(shí)現(xiàn)的方法主要有以下三種
(1):編譯器織入,要求使用特殊的編譯器
(2):類裝載期織入,要求使用特殊的類裝載器
(3):動(dòng)態(tài)代理織入
Spring使用動(dòng)態(tài)大理織入,AspectJ采用編譯期和類裝載期織入。
它是一種特殊的增強(qiáng),由于使用的不是很多,所以放在最后說(shuō)明。通過(guò)引介這種特殊的增強(qiáng),我們可以給類添加一些屬性和方法,例如讓某個(gè)類通過(guò)引介也實(shí)現(xiàn)某個(gè)接口并為該類添加接口的實(shí)現(xiàn)代碼。
Spring中的引介接口為:IntroductionInterceptor,Spring為該接口提供了實(shí)現(xiàn)類 DelegatingIntroductionInterceptor,一般情況下,我們只需要擴(kuò)展該實(shí)現(xiàn)類就可以定義自己的引介增強(qiáng)類了。
在后面還是基于代碼逐步的對(duì)Spring AOP進(jìn)行進(jìn)一步的說(shuō)明,包括各種實(shí)現(xiàn)方式。
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。