您好,登錄后才能下訂單哦!
在傳統(tǒng)的編寫(xiě)業(yè)務(wù)邏輯處理代碼時(shí),我們通常會(huì)習(xí)慣性地做幾件事情:日志記錄、事務(wù)控制及權(quán)限控制等,然后才是編寫(xiě)核心的業(yè)務(wù)邏輯處理代碼。當(dāng)代碼編寫(xiě)完成回頭再看時(shí),不禁發(fā)現(xiàn),揚(yáng)揚(yáng)灑灑上百行代碼中,真正用于核心業(yè)務(wù)邏輯處理才那么幾行,如圖6-4所示。方法復(fù)方法,類(lèi)復(fù)類(lèi),就這樣子帶著無(wú)可奈何遺憾地度過(guò)了多少個(gè)春秋。這倒也罷,倘若到了項(xiàng)目的尾聲,突然決定在權(quán)限控制上需要進(jìn)行大的變動(dòng)時(shí),成千上萬(wàn)個(gè)方法又得一一"登門(mén)拜訪",痛苦"雪上加霜"。
如果能把圖6-4中眾多方法中的所有共有代碼全部抽取出來(lái),放置到某個(gè)地方集中管理,然后在具體運(yùn)行時(shí),再由容器動(dòng)態(tài)織入這些共有代碼的話,最起碼可以解決兩個(gè)問(wèn)題:
Java EE程序員在編寫(xiě)具體的業(yè)務(wù)邏輯處理方法時(shí),只需關(guān)心核心的業(yè)務(wù)邏輯處理,既提高了工作效率,又使代碼變更簡(jiǎn)潔優(yōu)雅。
在日后的維護(hù)中由于業(yè)務(wù)邏輯代碼與共有代碼分開(kāi)存放,而且共有代碼是集中存放的,因此使維護(hù)工作變得簡(jiǎn)單輕松。
面向切面編程AOP技術(shù)就是為解決這個(gè)問(wèn)題而誕生的,切面就是橫切面,如圖6-5所示,代表的是一個(gè)普遍存在的共有功能,例如,日志切面、權(quán)限切面及事務(wù)切面等。
下面我們以用戶(hù)管理業(yè)務(wù)邏輯組件UserService的AOP實(shí)現(xiàn)過(guò)程(見(jiàn)圖6-6)為例,深度剖析一下AOP技術(shù)的實(shí)現(xiàn)原理。AOP技術(shù)是建立在Java語(yǔ)言的反射機(jī)制與動(dòng)態(tài)代理機(jī)制之上的。業(yè)務(wù)邏輯組件在運(yùn)行過(guò)程中,AOP容器會(huì)動(dòng)態(tài)創(chuàng)建一個(gè)代理對(duì)象供使用者調(diào)用,該代理對(duì)象已經(jīng)按Java EE程序員的意圖將切面成功切入到目標(biāo)方法的連接點(diǎn)上,從而使切面的功能與業(yè)務(wù)邏輯的功能同時(shí)得以執(zhí)行。從原理上講,調(diào)用者直接調(diào)用的其實(shí)是AOP容器動(dòng)態(tài)生成的代理對(duì)象,再由代理對(duì)象調(diào)用目標(biāo)對(duì)象完成原始的業(yè)務(wù)邏輯處理,而代理對(duì)象則已經(jīng)將切面與業(yè)務(wù)邏輯方法進(jìn)行了合成。
現(xiàn)將圖6-6中涉及到的一些概念解釋如下。
切面(Aspect):其實(shí)就是共有功能的實(shí)現(xiàn)。如日志切面、權(quán)限切面、事務(wù)切面等。在實(shí)際應(yīng)用中通常是一個(gè)存放共有功能實(shí)現(xiàn)的普通Java類(lèi),之所以能被AOP容器識(shí)別成切面,是在配置中指定的。
通知(Advice):是切面的具體實(shí)現(xiàn)。以目標(biāo)方法為參照點(diǎn),根據(jù)放置的地方不同,可分為前置通知(Before)、后置通知(AfterReturning)、異常通知(AfterThrowing)、最終通知(After)與環(huán)繞通知(Around)5種。在實(shí)際應(yīng)用中通常是切面類(lèi)中的一個(gè)方法,具體屬于哪類(lèi)通知,同樣是在配置中指定的。
連接點(diǎn)(Joinpoint):就是程序在運(yùn)行過(guò)程中能夠插入切面的地點(diǎn)。例如,方法調(diào)用、異常拋出或字段修改等,但Spring只支持方法級(jí)的連接點(diǎn)。
切入點(diǎn)(Pointcut):用于定義通知應(yīng)該切入到哪些連接點(diǎn)上。不同的通知通常需要切入到不同的連接點(diǎn)上,這種精準(zhǔn)的匹配是由切入點(diǎn)的正則表達(dá)式來(lái)定義的。
目標(biāo)對(duì)象(Target):就是那些即將切入切面的對(duì)象,也就是那些被通知的對(duì)象。這些對(duì)象中已經(jīng)只剩下干干凈凈的核心業(yè)務(wù)邏輯代碼了,所有的共有功能代碼等待AOP容器的切入。
代理對(duì)象(Proxy):將通知應(yīng)用到目標(biāo)對(duì)象之后被動(dòng)態(tài)創(chuàng)建的對(duì)象??梢院?jiǎn)單地理解為,代理對(duì)象的功能等于目標(biāo)對(duì)象的核心業(yè)務(wù)邏輯功能加上共有功能。代理對(duì)象對(duì)于使用者而言是透明的,是程序運(yùn)行過(guò)程中的產(chǎn)物。
織入(Weaving):將切面應(yīng)用到目標(biāo)對(duì)象從而創(chuàng)建一個(gè)新的代理對(duì)象的過(guò)程。這個(gè)過(guò)程可以發(fā)生在編譯期、類(lèi)裝載期及運(yùn)行期,當(dāng)然不同的發(fā)生點(diǎn)有著不同的前提條件。譬如發(fā)生在編譯期的話,就要求有一個(gè)支持這種AOP實(shí)現(xiàn)的特殊編譯器;發(fā)生在類(lèi)裝載期,就要求有一個(gè)支持AOP實(shí)現(xiàn)的特殊類(lèi)裝載器;只有發(fā)生在運(yùn)行期,則可直接通過(guò)Java語(yǔ)言的反射機(jī)制與動(dòng)態(tài)代理機(jī)制來(lái)動(dòng)態(tài)實(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)容。