Spring AOP簡述

什么是AOP

Aspect Oriented Programming:面向切面編程

什么時(shí)候會(huì)出現(xiàn)面向切面編程的需求票灰?

按照軟件重構(gòu)的思想直颅,如果多個(gè)類中出現(xiàn)重復(fù)的代碼吐根,就應(yīng)該考慮定義一個(gè)共同的抽象類迄损,將這些共同的代碼提取到抽象類中,比如Teacher,Student都有username,那么就可以把username及相關(guān)的get轧膘、set方法抽取到SysUser中败富,這種情況,我們稱為縱向抽取拢锹。

但是如果谣妻,我們的情況是以下情況,又該怎么辦卒稳?

給所有的類方法添加性能檢測蹋半,事務(wù)控制,該怎么抽瘸淇印减江?

PerformanceMonitor

TransactionManager

AOP就是希望將這些分散在各個(gè)業(yè)務(wù)邏輯代碼中的相同代碼染突,通過橫向切割的方式抽取到一個(gè)獨(dú)立的模塊中,讓業(yè)務(wù)邏輯類依然保存最初的單純辈灼。


抽取出來簡單份企,難點(diǎn)就是如何將這些獨(dú)立的邏輯融合到業(yè)務(wù)邏輯中,完成跟原來一樣的業(yè)務(wù)邏輯巡莹,這就是AOP解決的主要問題司志。

AOP術(shù)語

l連接點(diǎn)(Joinpoint)

程序執(zhí)行的某個(gè)特定位置,如某個(gè)方法調(diào)用前降宅,調(diào)用后骂远,方法拋出異常后,這些代碼中的特定點(diǎn)稱為連接點(diǎn)腰根。簡單來說激才,就是在哪加入你的邏輯增強(qiáng)

l切點(diǎn)(PointCut

每個(gè)程序的連接點(diǎn)有多個(gè),如何定位到某個(gè)感興趣的連接點(diǎn)额嘿,就需要通過切點(diǎn)來定位贸营。

比如,連接點(diǎn)--數(shù)據(jù)庫的記錄岩睁,切點(diǎn)--查詢條件

l增強(qiáng)(Advice

增強(qiáng)是織入到目標(biāo)類連接點(diǎn)上的一段程序代碼钞脂。

在Spring中,像BeforeAdvice等還帶有方位信息

l目標(biāo)對象(Target

需要被加強(qiáng)的業(yè)務(wù)對象

l織入(Weaving

織入就是將增強(qiáng)添加到對目標(biāo)類具體連接點(diǎn)上的過程捕儒。

l代理類(Proxy

一個(gè)類被AOP織入增強(qiáng)后冰啃,就產(chǎn)生了一個(gè)代理類。

l切面(Aspect

切面由切點(diǎn)和增強(qiáng)組成刘莹,它既包括了橫切邏輯的定義阎毅,也包括了連接點(diǎn)的定義,SpringAOP就是將切面所定義的橫切邏輯織入到切面所制定的連接點(diǎn)中点弯。

userBiz add update del

couseBiz add update del

定義一個(gè)范圍給哪些類的哪些方法

增強(qiáng):加事務(wù)的控制

AOP實(shí)現(xiàn)者

lAspectJ

AspectJ是語言級的AOP實(shí)現(xiàn)扇调,2001發(fā)布,擴(kuò)展了Java語言抢肛,定義了AOP語法狼钮,能夠在編譯期通過提供橫切代碼的織入,所以它有一個(gè)專門的編譯器用來生成遵守Java字節(jié)碼規(guī)范的class文件

lSpringAOP

SpringAOP使用純Java實(shí)現(xiàn)捡絮,在運(yùn)行期通過代理的方式向目標(biāo)類織入增強(qiáng)代碼熬芜。

SpringAOP代理機(jī)制

基于JDK的動(dòng)態(tài)代理,接口

基于CGlib的動(dòng)態(tài)代理福稳,類

問題

現(xiàn)有一個(gè)UserDao的實(shí)現(xiàn)涎拉,想在原有的實(shí)現(xiàn)基礎(chǔ)上添加新的業(yè)務(wù)處理,怎么辦?

假如有多個(gè)實(shí)現(xiàn)

什么是代理模式


我們假設(shè)有一個(gè)UserDao和一個(gè)TransactionManager類


靜態(tài)代理的問題:

1鼓拧,假如還有其他的dao半火,則還需要再創(chuàng)建新的proxy

2,如果目標(biāo)對象的方法發(fā)生改變季俩,比如方法名做了修改慈缔,則代理類也要做修改

基于JDK的動(dòng)態(tài)代理

關(guān)鍵類:

InvocationHandler:其作用就是將橫切邏輯代碼和業(yè)務(wù)邏輯代碼編織到一起的編織器。

Proxy則通過newProxyInstance根據(jù)handler來創(chuàng)建一個(gè)符合第三方接口的代理類

基于接口的模式

基于CGlib的動(dòng)態(tài)代理

CGlib采用非常底層的字節(jié)碼技術(shù)种玛,可以為一個(gè)類創(chuàng)建子類藐鹤,并在子類中采用方法攔截技術(shù)攔截所有父類方法的調(diào)用,并織入橫切邏輯

擴(kuò)展

如果要多層怎么辦赂韵?

AOP小結(jié)

這種實(shí)現(xiàn)方式存在三個(gè)明顯需要改進(jìn)的地方:

1.目標(biāo)類的所有方法都添加了性能監(jiān)視橫切邏輯娱节,而有時(shí),這并不是我們所期望的祭示,我們可能只希望對業(yè)務(wù)類中的某些特定方法添加橫切邏輯肄满;

2.我們通過硬編碼的方式指定了織入橫切邏輯的織入點(diǎn),即在目標(biāo)類業(yè)務(wù)方法的開始和結(jié)束前織入代碼质涛;

3.我們手工編寫代理實(shí)例的創(chuàng)建過程稠歉,為不同類創(chuàng)建代理時(shí),需要分別編寫相應(yīng)的創(chuàng)建代碼汇陆,無法做到通用怒炸。

Spring AOP的主要工作就是圍繞以上三點(diǎn)展開:Spring

AOP通過Pointcut(切點(diǎn))指定在哪些類的哪些方法上織入橫切邏輯,通過Advice(增強(qiáng))描述橫切邏輯和方法的具體織入點(diǎn)(方法前毡代、方法后阅羹、方法的兩端等)。此外教寂,Spring通過Advisor(切面)將Pointcut和Advice兩者組裝起來捏鱼。有了Advisor的信息,Spring就可以利用JDK或CGLib的動(dòng)態(tài)代理技術(shù)采用統(tǒng)一的方式為目標(biāo)Bean創(chuàng)建織入切面的代理對象了酪耕。

創(chuàng)建增強(qiáng)

Spring使用增強(qiáng)類定義橫切邏輯导梆,同時(shí)由于Spring只支持方法連接點(diǎn),增強(qiáng)還包括了在方法的哪一點(diǎn)加入橫切代碼的方位信息迂烁,所以增強(qiáng)既包含橫切邏輯看尼,還包含部分連接點(diǎn)的信息

增強(qiáng)類型

AOP聯(lián)盟為增強(qiáng)定義了org.aopalliance.aop.Advice接口,Spring支持5種類型的增強(qiáng)

前置增強(qiáng):org.springframework.aop.BeforeAdvice代表前置增強(qiáng)婚被,因?yàn)镾pring只支持方法級的增強(qiáng)狡忙,所以MethodBeforeAdvice是目前可用的前置增強(qiáng),表示在目標(biāo)方法執(zhí)行前實(shí)施增強(qiáng)址芯,而BeforeAdvice是為了將來版本擴(kuò)展需要而定

后置增強(qiáng):org.springframework.aop.AfterReturningAdvice代表后增強(qiáng),表示在目標(biāo)方法執(zhí)行后實(shí)施增強(qiáng);

環(huán)繞增強(qiáng):org.aopalliance.intercept.MethodInterceptor代表環(huán)繞增強(qiáng)谷炸,表示在目標(biāo)方法執(zhí)行前后實(shí)施增強(qiáng)北专;

異常拋出增強(qiáng):org.springframework.aop.ThrowsAdvice代表拋出異常增強(qiáng),表示在目標(biāo)方法拋出異常后實(shí)施增強(qiáng)旬陡;

案例:

創(chuàng)建切面

我們可能注意到一個(gè)問題:增強(qiáng)被織入到目標(biāo)類的所有方法中拓颓,假設(shè)我們希望有選擇地織入到目標(biāo)類某些特定的方法中,就需要使用切點(diǎn)進(jìn)行目標(biāo)連接點(diǎn)的定位了描孟。描述連接點(diǎn)是進(jìn)行AOP編程最主要的工作

增強(qiáng)提供了連接點(diǎn)方位信息:如織入到方法前面驶睦、后面等,而切點(diǎn)進(jìn)一步描述織入到哪些類的哪些方法上匿醒。

Spring通過org.springframework.aop.Pointcut接口描述切點(diǎn)场航,Pointcut由ClassFilter和MethodMatcher構(gòu)成,它通過ClassFilter定位到某些特定類上廉羔,通過MethodMatcher定位到某些特定方法上溉痢,這樣Pointcut就擁有了描述某些類的某些特定方法的能力。

Spring使用org.springframework.aop.Advisor接口表示切面的概念憋他,一個(gè)切面同時(shí)包含橫切代碼和連接點(diǎn)信息

從廣義上說孩饼,增強(qiáng)其實(shí)就是一種最簡單的切面,它既包括橫切代碼也包括切點(diǎn)信息竹挡,只不過它的切點(diǎn)只是簡單的方法相對位置的信息镀娶。所以增強(qiáng)一般需要和切點(diǎn)聯(lián)合才可以表示一個(gè)更具實(shí)用性的切面。

AspectJ

Spring AOP揪罕,它包括基于XML配置的AOP和基于@AspcetJ注解的AOP汽畴,這兩種方法雖然在配置切面時(shí)的表現(xiàn)方式不同,但底層都是采用動(dòng)態(tài)代理技術(shù)(JDK代理或CGLib代理)耸序。Spring可以集成AspectJ忍些,但AspectJ本身并不屬于Spring AOP的范疇。

Spring在處理@Aspect注解表達(dá)式時(shí)坎怪,需要將Spring的asm模塊添加到類路徑中罢坝。asm是輕量級的字節(jié)碼處理框架,因?yàn)镴ava的反射機(jī)制無法獲取入?yún)⒚亮琒pring就利用asm處理@AspectJ中所描述的方法入?yún)⒚?/p>



也可以通過配置的方式來生成代理對象



工作原理:

首先嘁酿,在配置文件中引入aop命名空間,然后通過aop命名空間的自動(dòng)為Spring容器中那些匹配@AspectJ切面的Bean創(chuàng)建代理男应,完成切面織入闹司。




最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市沐飘,隨后出現(xiàn)的幾起案子游桩,更是在濱河造成了極大的恐慌牲迫,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,386評論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件借卧,死亡現(xiàn)場離奇詭異盹憎,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)铐刘,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,142評論 3 394
  • 文/潘曉璐 我一進(jìn)店門陪每,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人镰吵,你說我怎么就攤上這事檩禾。” “怎么了疤祭?”我有些...
    開封第一講書人閱讀 164,704評論 0 353
  • 文/不壞的土叔 我叫張陵盼产,是天一觀的道長。 經(jīng)常有香客問我画株,道長辆飘,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,702評論 1 294
  • 正文 為了忘掉前任谓传,我火速辦了婚禮蜈项,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘续挟。我一直安慰自己紧卒,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,716評論 6 392
  • 文/花漫 我一把揭開白布诗祸。 她就那樣靜靜地躺著跑芳,像睡著了一般。 火紅的嫁衣襯著肌膚如雪直颅。 梳的紋絲不亂的頭發(fā)上博个,一...
    開封第一講書人閱讀 51,573評論 1 305
  • 那天,我揣著相機(jī)與錄音功偿,去河邊找鬼盆佣。 笑死,一個(gè)胖子當(dāng)著我的面吹牛械荷,可吹牛的內(nèi)容都是我干的共耍。 我是一名探鬼主播,決...
    沈念sama閱讀 40,314評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼吨瞎,長吁一口氣:“原來是場噩夢啊……” “哼痹兜!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起颤诀,我...
    開封第一講書人閱讀 39,230評論 0 276
  • 序言:老撾萬榮一對情侶失蹤字旭,失蹤者是張志新(化名)和其女友劉穎对湃,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體谐算,經(jīng)...
    沈念sama閱讀 45,680評論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡熟尉,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,873評論 3 336
  • 正文 我和宋清朗相戀三年归露,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了洲脂。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,991評論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡剧包,死狀恐怖恐锦,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情疆液,我是刑警寧澤一铅,帶...
    沈念sama閱讀 35,706評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站堕油,受9級特大地震影響潘飘,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜掉缺,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,329評論 3 330
  • 文/蒙蒙 一卜录、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧眶明,春花似錦艰毒、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,910評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至蜀肘,卻和暖如春绊汹,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背扮宠。 一陣腳步聲響...
    開封第一講書人閱讀 33,038評論 1 270
  • 我被黑心中介騙來泰國打工西乖, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人涵卵。 一個(gè)月前我還...
    沈念sama閱讀 48,158評論 3 370
  • 正文 我出身青樓浴栽,卻偏偏與公主長得像,于是被迫代替她去往敵國和親轿偎。 傳聞我的和親對象是個(gè)殘疾皇子典鸡,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,941評論 2 355

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

  • 本章內(nèi)容: 面向切面編程的基本原理 通過POJO創(chuàng)建切面 使用@AspectJ注解 為AspectJ切面注入依賴 ...
    謝隨安閱讀 3,147評論 0 9
  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn)坏晦,斷路器萝玷,智...
    卡卡羅2017閱讀 134,657評論 18 139
  • AOP實(shí)現(xiàn)可分為兩類(按AOP框架修改源代碼的時(shí)機(jī)): 靜態(tài)AOP實(shí)現(xiàn):AOP框架在編譯階段對程序進(jìn)行修改球碉,即實(shí)現(xiàn)...
    數(shù)獨(dú)題閱讀 2,317評論 0 22
  • 團(tuán)隊(duì)開發(fā)框架實(shí)戰(zhàn)—面向切面的編程 AOP 引言 軟件開發(fā)的目標(biāo)是要對世界的部分元素或者信息流建立模型蜓斧,實(shí)現(xiàn)軟件系統(tǒng)...
    Bobby0322閱讀 4,151評論 4 49
  • 什么是Spring Spring是一個(gè)開源的Java EE開發(fā)框架。Spring框架的核心功能可以應(yīng)用在任何Jav...
    jemmm閱讀 16,464評論 1 133