AOP最近被炒得非常的熱,各種各樣的AOP框架層出不窮。在AOP方面,我無意于去做一個完整的框架,支持各種AOP的特性,其實從實際我們項目經歷上來分析。可以得出,在絕大多數情況下,AOP的很多高級特性是用不上的,比如靜態代碼注入。為類添加運行時的構造函數,改變類的繼承關系等等。其實我們最常用的還是攔截器,關于這個話題,可能是比較有爭議的,畢竟每個人的立場和觀點是不同的。針對我目前所涉及的應用域來講,一個完整的攔截器框架已經足夠了。
一個典型的攔截器框架至少應該包括三個部分:
1、可聲明的攔截點;
2、靈活的攔截器序列;
3、對攔截對象的代理封裝;
攔截點可以基于具體的應用環境去靈活申明,這點可以參考Cocoon里的Pipeline。這里不用多說,大家看了后續的攔截點的定義代碼就一目了然了。關于攔截器的具體定義,也在隨后的部分提供,這里首先探討被攔截對象的代理的實現機制。
所謂代理,就是對被攔截對象的一個包裝,通過該包裝類,可以非常自然的對被包裝對象添加我們自定義的行為,比如調用攔截器進行攔截操作。
我們來看AOP的代理接口的定義:
package
org.sunny.core.aop;
import
java.lang.reflect.InvocationHandler;
import
org.sunny.exception.SunnyException;
import
java.util.List;
/**
*
該類是一個攔截器的處理中心,所有的業務邏輯的方法調用都會被該類攔截。通過這種機制,
*
在這里就可以統一的實現如下的過濾器:
*
1、方法級鑒權;
*
2、業務日志;
*
3、靜態屬性過濾。
*
等等功能。此外,你可以實現自己的攔截器,通過如下的接口:
*
< code>
*
< br>org.sunny.core.aop.interceptor.Interceptor
*
< /code>
*
并在全局配置文件里完成攔截器的配置。該攔截器就可以生效。
*
< p>Copyright:
Copyright
(c)
2005< /p>
*
< p>Company:
Sunny虛擬開發組< /p>
*
@author
高雁冰
*
@version
1.0
*/
public
interface
AopProxy
{
????/** ????*設置該動態代理需要代理的對象 ????*@paramdelegate具體被代理的對象(實例) ????*/ ????publicvoidsetDelegate(Objectdelegate); ???? ????/** ????*獲取通過該動態代理處理后的業務代理對象 ????*@return該代理處理后的代理業務對象 ????*@throwsSunnyException ????*/ ????publicObjectgetProxy()throwsSunnyException; ???? ????/** ????*設置該代理類需要處理的所有攔截器。 ????*@paraminterceptors攔截器集合 ????*/ ????publicvoidsetInterceptors(Listinterceptors); ???? } |
-----------------------------
Sunny目前提供了兩種代理的實現方式:
1、基于Java的動態代理,原理大家可以到java.sun.com站點上去研究一番;
2、基于Cglib的字節碼映射的方式,這點大家也可以關注Cglig來找到具體的答案。
需要說明的是,這兩種代理各自有不同的應用域,某些情況是不能通用的。基于Java的動態代理要求被代理對象必須基于接口編程,即每個被代理對象有一個明確的接口。而基于Cglib的代理則不在此限制。
下面貼出源代碼:
----------------------------------------
package
org.sunny.core.aop;
//import
java.lang.reflect.*;
import
org.sunny.exception.SunnyException;
import
org.sunny.cfg.PltMessage;
import
org.sunny.core.aop.interceptor.InterceptorUtil;
import
java.lang.reflect.InvocationHandler;
import
java.lang.reflect.Method;
import
java.util.List;
/**
*
采用Java動態代理的方式實現攔截器機制。
*
Copyright:
Copyright
(c)
2005
*
< p>Company:
Sunny虛擬開發組< /p>
*
@author
高雁冰({@link
mailto:haiger@163.com})
*
@version
1.0
*/
public
class
DynamicProxy
implements
AopProxy,InvocationHandler
{
????privateObjectdelegate;//具體代理的業務邏輯對象 ????privateInterceptorUtilinterceptorUtil; ???? ????/** ????*默認構造函數,由于該動態代理的實現需要通過Class.newInstance來調用(被框架),所以需要 ????*提供該默認構造函數,需要注意的是。在這之后,需要調用該類的setDelegate方法來具體設置該 ????*類具體代理哪個對象。 ????*/ ????publicDynamicProxy() ????{ ????????//... ????} ???? ???? ????/** ????*IOC機制,通過運行時傳入需要代理的業務邏輯對象。 ????*@paramdelegate需要代理的業務邏輯對象 ????*/ ????publicDynamicProxy(Objectdelegate) ????{ ????????setDelegate(delegate); ????} ???? ????/** ????*設置該動態代理需要代理的對象 ????*@paramdelegate具體被代理的對象(實例) ????*/ ????publicvoidsetDelegate(Objectdelegate) ????{ ????????this.delegate=delegate; ????} ???? ????/** ????*設置該代理類需要處理的所有攔截器。 ????*@paraminterceptors攔截器集合 ????*/ ????publicvoidsetInterceptors(Listinterceptors) ????{ ????????interceptorUtil=newInterceptorUtil(interceptors); ????} ???? ????/** ????*獲取通過該動態代理處理后的業務代理對象 ????*@return該代理處理后的代理業務對象 ????*@throwsSunnyException ????*/ ????publicObjectgetProxy()throwsSunnyException ????{ ????????if(null==delegate) ????????{ ????????????thrownewSunnyException(PltMessage.getInstance().getMessage( ????????????"BLA_IMPL_DELEGATE_NOT_SET")); ????????} ???????? ????????//構造該業務邏輯的包裝類 ????????Objectproxy=java.lang.reflect.Proxy.newProxyInstance( ????????delegate.getClass().getClassLoader(), ????????delegate.getClass().getInterfaces() ????????,this); ???????? ????????returnproxy; ????} ???? ???? ????/** ????*攔截器的方法實現,該方法調用代理的業務邏輯的方法。 ????*@paramproxy被代理的類 ????*@parammethod被調用的業務方法 ????*@paramargs調用業務方法的輸入參數 ????*@returnObject業務方法調用的返回值 ????*@throwsThrowable業務方法拋出的異常,該異常目前在外圍系統去捕獲的時候需要一些 ????*技巧,你應該這樣(用getCause()方法)來捕獲原始拋出的異常(范例代碼) ????*< code> ????*< br>try ????*< br>{ ????*< br>... ????*< br>}catch(Throwabletb) ????*< br>{ ????*< br>System.out.println(tb.getCause().getMessage()); *< br>} *< /code>歲 */ publicObjectinvoke(Objectproxy,Methodmethod,Object[]args)throws Throwable { ????//調用所有的攔截器,對方法行為進行攔截操作 ????interceptorUtil.before(delegate,method,args); ???? ????//具體業務邏輯方法的調用 ????Objectresult=null; ????try ????{ ????????result=method.invoke(delegate,args); ????}catch(Throwablee) ????{ ????????//對日志進行攔截操作 ????????interceptorUtil.exception(delegate,method,args,e); ????} ???? ????//業務邏輯調用完成,對結果進行攔截操作 ????interceptorUtil.after(delegate,method,args,result); ???? ????returnresult; } }
|
---------------Cglib代理類--------------------
packageorg.sunny.core.aop;
importjava.lang.reflect.Method; importnet.sf.cglib.proxy.MethodInterceptor; importnet.sf.cglib.proxy.Enhancer; importnet.sf.cglib.proxy.MethodProxy; importorg.sunny.exception.SunnyException; importorg.sunny.cfg.PltMessage; importorg.sunny.core.aop.interceptor.InterceptorUtil; importjava.util.List; /** *采用Cglib代理的方式實現攔截器機制。需要注意的是: *由于目前EJB的實現方式是采用靜態-動態Stub的實現。Cgblib在這種對象的代理生成上有一 *些問題,(EJB的Object的Stub是一個Finnal的類,不能完成代理),因此,如果系統采用EJB作為 *業務邏輯,則攔截器引擎只能使用: *< code> *org.sunny.blaccess.impl.DynanicProxyReactor *< /code> *Copyright:Copyright(c)2005 *< p>Company:Sunny虛擬開發組< /p> *@author高雁冰({@linkmailto:haiger@163.com}) *@version1.5 */
publicclassCglibProxyimplementsMethodInterceptor,AopProxy { ????privateObjectdelegate;//被代理的業務對象 ????privateEnhancerenhancer=newEnhancer(); ????privateInterceptorUtilinterceptorUtil; ???? ????/** ????*設置該動態代理需要代理的對象 ????*@paramdelegate具體被代理的對象(實例) ????*/ ????publicvoidsetDelegate(Objectdelegate) ????{ ????????this.delegate=delegate; ????} ???? ????/** ????*設置該代理類需要處理的所有攔截器。 ????*@paraminterceptors攔截器集合 ????*/ ????publicvoidsetInterceptors(Listinterceptors) ????{ ????????interceptorUtil=newInterceptorUtil(interceptors); ????} ???? ????/** ????*獲取通過該動態代理處理后的業務代理對象 ????*@return該代理處理后的代理業務對象 ????*@throwsSunnyException ????*/ ????publicObjectgetProxy()throwsSunnyException ????{ ????????if(null==delegate) ????????{ ????????????thrownewSunnyException(PltMessage.getInstance().getMessage( ????????????"BLA_IMPL_DELEGATE_NOT_SET")); ????????} ????????if(-1!=delegate.getClass().getName().indexOf("$$")) ????????{ ????????????enhancer.setSuperclass(delegate.getClass().getSuperclass()); ????????????}else ????????????{ ????????????????enhancer.setSuperclass(delegate.getClass()); ????????????} ????????????enhancer.setCallback(this); ????????????returnenhancer.create(); ????????} ???????? ????????/** ????????*實現對業務邏輯方法的具體攔截操作。在該操作里,可以在業務邏輯方法調用前后或者拋出異常的 ????????*時候添加自己的控制,這里則選擇執行系統配置的攔截器。 ????????*@paramo被代理對象 ????????*@parammethod訪問的具體方法 ????????*@paramargs方法輸入參數 ????????*@paramproxy方法代理 ????????*@return方法執行結果 ????????*@throwsjava.lang.Throwable ????????*/ ????????publicObjectintercept(Objecto,Methodmethod,Object[]args,MethodProxyproxy) ????????throwsThrowable ????????{ ????????????//調用所有的攔截器,對方法行為進行攔截操作 ????????????interceptorUtil.before(delegate,method,args); ???????????? ????????????//具體業務邏輯方法的調用 ????????????Objectresult=null; ????????????try ????????????{ ????????????????result=proxy.invokeSuper(o,args); ????????????}catch(Throwablee) ????????????{ ????????????????//對日志進行攔截操作 ????????????????interceptorUtil.exception(delegate,method,args,e); ????????????} ???????????? ????????????//業務邏輯調用完成,對結果進行攔截操作 ????????????interceptorUtil.after(delegate,method,args,result); ???????????? ????????????returnresult; ????????} ????????
|
posted on 2007-02-02 20:35
???MengChuChen 閱讀(284)
評論(0) 編輯 收藏 所屬分類:
Spring