spring aop
aop(aspect orient programming),也就是面向切面程式設計
。可以這樣理解,
物件導向程式設計(oop)是從靜態角度考慮程式結構,面向切面程式設計(aop)是從動態角度考慮程式執行過程。
在日常生活中,會遇到各種各樣的中介機構,比如獵頭公司,律師事務所,婚姻介紹所,房產公司等。在這些單位工作的人員均可稱為**人。**人的共同特徵是可以代替委託人去和第三方通訊。譬如:律師代替委託人打官司,獵頭代替委託人物色人才,紅娘代替委託人尋找物件,房產**人代替委託人出租房屋。
**人可以在第三方和委託人之間**或過濾訊息,但是不能取代委託人的任務。譬如你要找女朋友,委託你一要好的哥們去幫你物色,結果被他給物色了。這就不叫**。
**模式的作用是:為其他物件提供一種**以控制對這個物件的訪問。在某些情況下,乙個客戶不想或者不能直接引用另乙個物件,而**物件可以在客戶端和目標物件之間起到中介的作用。
先介紹aop的四種通知型別:
1、前置通知:在目標方法執行之前呼叫。
實現methodbeforeadvice介面,介面方法如下:
voidbefore(method
method,object
args,object
target) throws throwable
;這個介面為我們提供了獲得目標方法,引數,目標物件的機會。注意:我們沒必要在這個方法裡面呼叫目標方法(可以通過反射呼叫),因為,這個介面方法結束後目標方法將呼叫,這才叫前置嘛(在目標方法之前)。要想終止程式的繼續執行,只有拋異常或呼叫system.exit()
2、 後置通知:在目標方法執行之後呼叫。
實現afterreturningadvice介面,該介面方法如下:
voidafterreturning(objectreturnvalue,method
method,
object這個方法多了乙個目標方法的返回值引數。同理要結束程式流程只有拋異常和呼叫system.exit()方法。args, object
target) throws throwable
3、環繞通知:攔截目標方法的執行,可在該型別通知裡自行呼叫目標方法。
實現methodinterceptor介面,該介面在aopalliance.jar包裡,這個包是aop聯盟(aop程式設計介面,為實現aop程式設計介面重用)的包,可以理解成aop程式設計規範介面。
介面方法如下:
objectinvoke(methodinvocation invocation) throws throwable;
環繞通知和上述2個通知的區別:
1)由於環繞通知是攔截目標方法的執行,所以在這個方法裡使用者可以通過invocation.proceed()方法呼叫目標方法,這點和methodbeforeadvice不同,它的目標方法總是會執行,除非拋異常或執行system.exit()方法。
2)正常情況下這個方法返回的就是目標方法(invocation.proceed()返回的結果)的返回值,但可以在這個介面方法裡改變目標方法的返回值,除非必須如此,否則最好不要這樣使用。這個介面與aop聯盟的aop框架相容。
因為要顯示的呼叫目標方法(invocation.proceed()),所以更推薦使用上述2種方式。
4、異常通知:當目標方法丟擲異常時呼叫。
實現throwsadvice介面,該介面是標記介面,沒有定義任何乙個必須實現的方法,但實現該介面的類必須至少有乙個如下形式的方法:
下面看乙個aop例子
切面類testaspect
package com.spring.aop;
/** * 切面
* */
public class testaspect
public object doaround(proceedingjoinpoint pjp) throws throwable
public void dobefore(joinpoint jp)
public void dothrowing(joinpoint jp, throwable ex)
private void sendex(string ex)
}
package com.spring.service;
/** * 介面a
*/public inte***ce aservice
package com.spring.service;
/** *介面a的實現類
*/public class aserviceimpl implements aservice
public void fooa(string _msg)
}
package com.spring.service;
/** * service類b
*/public class bserviceimpl
public void foob()
}
<?xml version="1.0" encoding="utf-8"?>
測試類aoptest
public class aoptest extends abstractdependencyinjectionspringcontexttests
/*** 測試正常呼叫
*/public void testcall()
/*** 測試after-throwing
*/public void testthrow()
catch (illegalargumentexception e) }
public void setaservice(aservice service)
public void setbservice(bserviceimpl service)
}
執行結果如下:
log begining method: com.spring.service.aserviceimpl.fooa
aserviceimpl.fooa(msg:junit test fooa)
log ending method: com.spring.service.aserviceimpl.fooa
process time: 0 ms
log begining method: com.spring.service.aserviceimpl.bara
aserviceimpl.bara()
log ending method: com.spring.service.aserviceimpl.bara
process time: 0 ms
log begining method: com.spring.service.bserviceimpl.foob
bserviceimpl.foob()
log ending method: com.spring.service.bserviceimpl.foob
process time: 0 ms
log begining method: com.spring.service.bserviceimpl.barb
bserviceimpl.barb(msg:junit test barb type:0)
log ending method: com.spring.service.bserviceimpl.barb
process time: 0 ms
log begining method: com.spring.service.bserviceimpl.barb
bserviceimpl.barb(msg:junit call barb type:1)
log ending method: com.spring.service.bserviceimpl.barb
method com.spring.service.bserviceimpl.barb throw exception
測試異常
講解:
我們先看配置檔案中 有:before after around throw
測試類中順序為 fooa bara foob barb 還有乙個異常測試 barb
先從fooa開始,由於配置檔案中為 before after around throw 那麼對於fooa,就可以從 dobefore doafter doaround dothrow 開始
在做fooa之前 先 做before 做完fooa然後做 after 然後對於環繞通知共享前置後後置資訊
所以對於fooa 輸出為
log begining method: com.spring.service.aserviceimpl.fooa
aserviceimpl.fooa(msg:junit test fooa)
log ending method: com.spring.service.aserviceimpl.fooa
process time: 0 ms
至於為什麼會沒有throw因為在fooa執行過程中並沒有丟擲異常。
同理 其他的也這樣理解
Spring AOP面向切面程式設計
最近在系統中需要實現使用者某些操作新增積分,希望實現對系統現有的 進行最小嵌入,因此使用spring aop的切面程式設計將很好實現該需求,達到最小耦合度。在spring aop中的通知都是針對方法層級進行通知,相對與struct中針對類層級通知,具有更好的靈活性。方法攔截 methodinterc...
Spring AOP面向切面程式設計
一.常用概念 原有功能 切點 pointcut 前置通知 在切點之前執行的功能,before advice 後置通知 在切點之後執行的功能,after advice 異常通知 如果切點執行過程 現異常,則觸發異常通知 throws advice 切面 所有功能的總稱 織入 把切面嵌入到原有功能的過程...
Spring AOP 面向切面程式設計)
aop能夠將那些與業務無關,卻為業務模組所共同呼叫的邏輯或責任 例如事務處理 日誌管理 許可權控制等 封裝起來,便於減少系統的重複 降低模組間的耦合度,並有利於未來的可拓展性和可維護性。簡單例子 在某個專案裡,非管理員不能對某些業務進行操作,如下 從上面的 我們可以看出這種方式達到了許可權驗證的功能...