Aop編程(轉(zhuǎn))

Aop編程是一種區(qū)別OOP編程的概念豺裆,從切面的角度看待問題拒秘,這篇文章主要講述了Java開發(fā)中常用的Aop開發(fā)方式以及他們的優(yōu)缺點(diǎn)和區(qū)別号显。

什么是Aop編程

AOP為Aspect Oriented Programming的縮寫,意為:面向切面編程躺酒,通過預(yù)編譯方式和運(yùn)行期動(dòng)態(tài)代理實(shí)現(xiàn)程序功能的統(tǒng)一維護(hù)的一種技術(shù)押蚤。
AOP是OOP的延續(xù),是軟件開發(fā)中的一個(gè)熱點(diǎn)羹应,也是spring框架中的一個(gè)重要內(nèi)容揽碘,是函數(shù)式編程的一種衍生范型。利用AOP可以對(duì)業(yè)務(wù)邏輯的各個(gè)部分進(jìn)行隔離园匹,從而使得業(yè)務(wù)邏輯各部分之間的耦合度降低雳刺,提高程序的可重用性,同時(shí)提高了開發(fā)的效率裸违。

常見的使用場(chǎng)景

性能監(jiān)控: 在方法調(diào)用前后記錄調(diào)用時(shí)間掖桦,方法執(zhí)行太長(zhǎng)或超時(shí)報(bào)警。

緩存代理: 緩存某方法的返回值供汛,下次執(zhí)行該方法時(shí)枪汪,直接從緩存里獲取。

軟件破解: 使用AOP修改軟件的驗(yàn)證類的判斷邏輯怔昨。

記錄日志: 在方法執(zhí)行前后記錄系統(tǒng)日志料饥。

工作流系統(tǒng): 工作流系統(tǒng)需要將業(yè)務(wù)代碼和流程引擎代碼混合在一起執(zhí)行,那么我們可以使用AOP將其分離朱监,并動(dòng)態(tài)掛接業(yè)務(wù)岸啡。

權(quán)限驗(yàn)證: 方法執(zhí)行前驗(yàn)證是否有權(quán)限執(zhí)行當(dāng)前方法,沒有則拋出沒有權(quán)限執(zhí)行異常赫编,由業(yè)務(wù)代碼捕捉巡蘸。
如果對(duì)Aop的概念不理解,可以參考文章Aop那些事

JAVA中Aop的具體實(shí)現(xiàn)方式

1擂送、JDK動(dòng)態(tài)代理

有過java開發(fā)經(jīng)驗(yàn)的朋友都知道悦荒,java通過實(shí)現(xiàn)InvocationHandler接口,可以實(shí)現(xiàn)對(duì)一個(gè)類的動(dòng)態(tài)代理嘹吨,通過動(dòng)態(tài)代理搬味,我們可以生成代理類從而在代理類方法中,在執(zhí)行被代理類方法前后蟀拷,添加自己的實(shí)現(xiàn)內(nèi)容碰纬,從而實(shí)現(xiàn)Aop。

優(yōu)點(diǎn):動(dòng)態(tài)代理java自身支持问芬,不需要引入外部庫(kù)悦析,在運(yùn)行期通過接口動(dòng)態(tài)生成代理類

缺點(diǎn):首先代理類必須實(shí)現(xiàn)一個(gè)接口,如果沒實(shí)現(xiàn)接口會(huì)拋出一個(gè)異常此衅。第二性能影響强戴,因?yàn)閯?dòng)態(tài)代理使用反射的機(jī)制實(shí)現(xiàn)的亭螟,首先反射肯定比直接調(diào)用要慢

2、動(dòng)態(tài)字節(jié)碼生成

在運(yùn)行期骑歹,目標(biāo)類加載后预烙,動(dòng)態(tài)構(gòu)建字節(jié)碼文件生成目標(biāo)類的子類,將切面邏輯加入到子類中道媚,沒有接口也可以織入默伍,但擴(kuò)展類的實(shí)例方法為final時(shí),則無法進(jìn)行織入衰琐。

可以使用Cglib來實(shí)現(xiàn)動(dòng)態(tài)字節(jié)碼生成,這是一個(gè)強(qiáng)大的炼蹦,高性能羡宙,高質(zhì)量的Code生成類庫(kù),它可以在運(yùn)行期擴(kuò)展Java類與實(shí)現(xiàn)Java接口掐隐。CGLIB包的底層是通過使用一個(gè)小而快的字節(jié)碼處理框架ASM狗热,來轉(zhuǎn)換字節(jié)碼并生成新的類。

優(yōu)點(diǎn):可以織入沒有接口的類虑省;運(yùn)行時(shí)生成匿刮,減少不必要的生成開銷;通過字節(jié)碼生成子類探颈,而不是反射方式去調(diào)用代理類

缺點(diǎn):不能織入final方法熟丸;運(yùn)行時(shí)生成子類,說明會(huì)有生成開銷伪节,并且可能生成大量子類

3光羞、自定義類加載器

在運(yùn)行期,目標(biāo)加載前怀大,將切面邏輯加到目標(biāo)字節(jié)碼里纱兑。

可以對(duì)絕大部分類進(jìn)行織入,但代碼中如果使用了其他類加載器化借,則這些類將不會(huì)被織入潜慎。

Javassist是一個(gè)編輯字節(jié)碼的框架,可以讓你很簡(jiǎn)單地操作字節(jié)碼蓖康。它可以在運(yùn)行期定義或修改Class铐炫。使用Javassist實(shí)現(xiàn)AOP的原理是在字節(jié)碼加載前直接修改需要切入的方法。這比使用Cglib實(shí)現(xiàn)AOP更加高效蒜焊,并且沒太多限制.

優(yōu)點(diǎn):可以織入絕大部分類驳遵;運(yùn)行時(shí)生成,減少不必要的生成開銷山涡;通過將切面邏輯寫入字節(jié)碼堤结,減少了生成子類的開銷唆迁,不會(huì)產(chǎn)生過多子類

缺點(diǎn):運(yùn)行時(shí)加入切面邏輯,產(chǎn)生開銷竞穷;

4唐责、ASM

ASM 是一個(gè) Java 字節(jié)碼操控框架。它能夠以二進(jìn)制形式修改已有類或者動(dòng)態(tài)生成類瘾带。ASM 可以直接產(chǎn)生二進(jìn)制 class 文件鼠哥,也可以在類被加載入 Java 虛擬機(jī)之前動(dòng)態(tài)改變類行為。ASM 從類文件中讀入信息后看政,能夠改變類行為朴恳,分析類信息,甚至能夠根據(jù)用戶要求生成新類允蚣。

從上面的描述可以看出于颖,ASM可以在編譯期直接修改編譯出的字節(jié)碼文件,也可以像javassit一樣嚷兔,在運(yùn)行期森渐,類文件加載前,去修改字節(jié)碼。兩者的區(qū)別在于,一個(gè)將所有需要AOP的類都事先修改了皆刺,一個(gè)在運(yùn)行時(shí)需要才去修改。

優(yōu)點(diǎn):可以織入絕所有類耐齐;兩者生成方式,可以根據(jù)需求選擇

缺點(diǎn):修改字節(jié)碼蒋情,需要對(duì)class文件比較熟悉蚪缀,編寫過程復(fù)雜

5、AspectJ

AspectJ是一個(gè)面向切面的框架恕出,它擴(kuò)展了Java語(yǔ)言询枚。AspectJ定義了AOP語(yǔ)法所以它有一個(gè)專門的編譯器用來生成遵守Java字節(jié)編碼規(guī)范的Class文件。
和ASM一樣浙巫,Aspectj有靜態(tài)編譯和動(dòng)態(tài)編譯的優(yōu)點(diǎn)金蜀,供程序員選擇。另外Aspectj其編碼更為簡(jiǎn)潔的畴,是Android開發(fā)中渊抄,實(shí)現(xiàn)AOP的首選。

優(yōu)點(diǎn):可以織入絕所有類丧裁;兩者生成方式护桦,可以根據(jù)需求選擇;編寫簡(jiǎn)單煎娇,功能強(qiáng)大

缺點(diǎn):需要使用ajc編譯器編譯二庵,ajc編譯器是java編譯器的擴(kuò)展贪染,具有其所有功能

6、APT

自定義一個(gè)AbstractProcessor催享,在編譯期去解析編譯的類杭隙,并且根據(jù)需求生成一個(gè)實(shí)現(xiàn)了特定接口的子類(代理類),和JDK動(dòng)態(tài)代理不同的是因妙,代理類是在編譯期生成的痰憎。常見的一些Android的IOC框架中有大量應(yīng)用(就是通過注解代替findviewbyid等方法)。
詳情可以參考 Android 打造編譯時(shí)注解解析框架 這只是一個(gè)開始

這里順便說一句攀涵,目前Android注解解析框架主要有兩種實(shí)現(xiàn)方法铣耘,一種是運(yùn)行期通過反射去解析當(dāng)前類,注入相應(yīng)要運(yùn)行的方法以故,一種是在編譯期生成類的代理類蜗细,在運(yùn)行期直接調(diào)用代理類的代理方法。APT指的是后者据德。

這兩種實(shí)現(xiàn)方式,后者消耗更少跷车,但是會(huì)生成大量代理類棘利。

優(yōu)點(diǎn):可以織入絕所有類;編譯期代理朽缴,減少運(yùn)行時(shí)消耗

缺點(diǎn):需要使用apt編譯器編譯善玫;需要手動(dòng)拼接代理的代碼(其實(shí)是整個(gè)字符串);生成大量代理類

寫在最后

JAVA中AOP有多種實(shí)現(xiàn)方式密强,各有優(yōu)缺點(diǎn)茅郎,在實(shí)際項(xiàng)目中,我選擇了AspectJ或渤,因?yàn)樗膭?dòng)靜結(jié)合和編寫簡(jiǎn)單系冗,網(wǎng)上也有不少使用AspectJ來實(shí)現(xiàn)Android AOP的框架,例如https://github.com/JakeWharton/hugo薪鹦。

作者:六_六
鏈接:http://www.reibang.com/p/ffd534098e7d
來源:簡(jiǎn)書
著作權(quán)歸作者所有掌敬。商業(yè)轉(zhuǎn)載請(qǐng)聯(lián)系作者獲得授權(quán),非商業(yè)轉(zhuǎn)載請(qǐng)注明出處池磁。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末奔害,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子地熄,更是在濱河造成了極大的恐慌华临,老刑警劉巖,帶你破解...
    沈念sama閱讀 219,366評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件端考,死亡現(xiàn)場(chǎng)離奇詭異雅潭,居然都是意外死亡揭厚,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,521評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門寻馏,熙熙樓的掌柜王于貴愁眉苦臉地迎上來棋弥,“玉大人,你說我怎么就攤上這事诚欠⊥缛荆” “怎么了?”我有些...
    開封第一講書人閱讀 165,689評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵轰绵,是天一觀的道長(zhǎng)粉寞。 經(jīng)常有香客問我,道長(zhǎng)左腔,這世上最難降的妖魔是什么唧垦? 我笑而不...
    開封第一講書人閱讀 58,925評(píng)論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮液样,結(jié)果婚禮上振亮,老公的妹妹穿的比我還像新娘。我一直安慰自己鞭莽,他們只是感情好坊秸,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,942評(píng)論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著澎怒,像睡著了一般褒搔。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上喷面,一...
    開封第一講書人閱讀 51,727評(píng)論 1 305
  • 那天星瘾,我揣著相機(jī)與錄音,去河邊找鬼惧辈。 笑死琳状,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的盒齿。 我是一名探鬼主播算撮,決...
    沈念sama閱讀 40,447評(píng)論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼县昂!你這毒婦竟也來了肮柜?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,349評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤倒彰,失蹤者是張志新(化名)和其女友劉穎审洞,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,820評(píng)論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡芒澜,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,990評(píng)論 3 337
  • 正文 我和宋清朗相戀三年仰剿,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片痴晦。...
    茶點(diǎn)故事閱讀 40,127評(píng)論 1 351
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡南吮,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出誊酌,到底是詐尸還是另有隱情部凑,我是刑警寧澤,帶...
    沈念sama閱讀 35,812評(píng)論 5 346
  • 正文 年R本政府宣布碧浊,位于F島的核電站涂邀,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏箱锐。R本人自食惡果不足惜比勉,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,471評(píng)論 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望驹止。 院中可真熱鬧浩聋,春花似錦、人聲如沸臊恋。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,017評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)捞镰。三九已至闸与,卻和暖如春毙替,著一層夾襖步出監(jiān)牢的瞬間岸售,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,142評(píng)論 1 272
  • 我被黑心中介騙來泰國(guó)打工厂画, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留凸丸,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,388評(píng)論 3 373
  • 正文 我出身青樓袱院,卻偏偏與公主長(zhǎng)得像屎慢,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子忽洛,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,066評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容

  • Android 自定義View的各種姿勢(shì)1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 172,182評(píng)論 25 707
  • 朋友兒子的婚禮熱鬧非凡腻惠,也促成幾十年未見的兒時(shí)小伙伴們的相聚,曾經(jīng)稚嫩青春的面孔一去不復(fù)返欲虚,平添了許多滄桑集灌,時(shí)...
    明珠hmz閱讀 524評(píng)論 2 4
  • 寂靜的咖啡廳,她在一個(gè)不起眼的角落里坐著复哆,桌上的一杯咖啡早已涼透欣喧。她卻毫不關(guān)心腌零,眼睛直直的盯著窗外的世界。 ...
    陌晨啦閱讀 314評(píng)論 0 2