【永恒的瞬間】
          ?Give me hapy ?

          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 閱讀(290) 評論(0)  編輯  收藏 所屬分類: Spring
          主站蜘蛛池模板: 华池县| 曲松县| 留坝县| 惠州市| 林周县| 外汇| 蒲江县| 精河县| 连江县| 清涧县| 新源县| 晋中市| 岳西县| 莱西市| 海丰县| 武安市| 博野县| 应用必备| 蒙城县| 夏津县| 舞钢市| 陵川县| 涞水县| 雅安市| 衡南县| 吉安市| 肃北| 江孜县| 桐庐县| 麦盖提县| 谢通门县| 娄底市| 三都| 庆云县| 丰原市| 北安市| 东乡县| 乐昌市| 桃源县| 浦县| 南充市|