AOP最近被炒得非常的熱,各種各樣的AOP框架層出不窮。在AOP方面,我無意于去做一個完整的框架,支持各種AOP的特性,其實從實際我們項目經歷上來分析。可以得出,在絕大多數情況下,AOP的很多高級特性是用不上的,比如靜態代碼注入。為類添加運行時的構造函數,改變類的繼承關系等等。其實我們最常用的還是攔截器,關于這個話題,可能是比較有爭議的,畢竟每個人的立場和觀點是不同的。針對我目前所涉及的應用域來講,一個完整的攔截器框架已經足夠了。
一個典型的攔截器框架至少應該包括三個部分:
1、可聲明的攔截點;
2、靈活的攔截器序列;
3、對攔截對象的代理封裝;
攔截點可以基于具體的應用環境去靈活申明,這點可以參考Cocoon里的Pipeline。這里不用多說,大家看了后續的攔截點的定義代碼就一目了然了。關于攔截器的具體定義,也在隨后的部分提供,這里首先探討被攔截對象的代理的實現機制。
所謂代理,就是對被攔截對象的一個包裝,通過該包裝類,可以非常自然的對被包裝對象添加我們自定義的行為,比如調用攔截器進行攔截操作。
我們來看AOP的代理接口的定義:
-----------------------------
Sunny目前提供了兩種代理的實現方式:
1、基于Java的動態代理,原理大家可以到java.sun.com站點上去研究一番;
2、基于Cglib的字節碼映射的方式,這點大家也可以關注Cglig來找到具體的答案。
需要說明的是,這兩種代理各自有不同的應用域,某些情況是不能通用的。基于Java的動態代理要求被代理對象必須基于接口編程,即每個被代理對象有一個明確的接口。而基于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; ????????} ???????? |