<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    隨筆 - 45, 文章 - 6, 評論 - 4, 引用 - 0
    數據加載中……

    JAVA代理模式

    代理模式
    代理模式的作用是:為其他對象提供一種代理以控制對這個對象的訪問。在某些情況下,一個客戶不想或者不能直接引用另一個對象,而代理對象可以在客戶端和目標對象之間起到中介的作用。

    代理模式一般涉及到的角色有:

    抽象角色:聲明真實對象和代理對象的共同接口;

    代理角色:代理對象角色內部含有對真實對象的引用,從而可以操作真實對象,同時代理對象提供與真實對象相同的接口以便在任何時刻都能代替真實對象。同時,代理對象可以在執行真實對象操作時,附加其他的操作,相當于對真實對象進行封裝。

    真實角色:代理角色所代表的真實對象,是我們最終要引用的對象。(參見文獻1)

    以下以《Java與模式》中的示例為例:

     

    抽象角色:

    abstract public class
     Subject

    {

        
    abstract public void
     request();

    }


    真實角色:實現了Subject的request()方法。

    public class RealSubject extends Subject 

    {

           
    public
     RealSubject()

           


           }


           

           
    public void request()

           


                  System.out.println(
    "From real subject."
    );

           }


    }


    代理角色:

    public class ProxySubject extends Subject 

    {

        
    private RealSubject realSubject; //以真實角色作為代理角色的屬性


           

           
    public ProxySubject()

           
    {

           }



           
    public void request() //該方法封裝了真實對象的request方法

           
    {

            preRequest(); 

                  
    if( realSubject == null
     )

            
    {

                         realSubject 
    = new
     RealSubject();

                  }


            realSubject.request(); 
    //此處執行真實對象的request方法

            postRequest(); 

           }



        
    private void preRequest()

        
    {

            
    //something you want to do before requesting


        }



        
    private void postRequest()

        
    {

            
    //something you want to do after requesting


        }


    }


    客戶端調用:

    Subject sub
    =new ProxySubject();

    Sub.request();
            由以上代碼可以看出,客戶實際需要調用的是RealSubject類的request()方法,現在用ProxySubject來代理RealSubject類,同樣達到目的,同時還封裝了其他方法(preRequest(),postRequest()),可以處理一些其他問題。

    2.動態代理類

           Java動態代理類位于Java.lang.reflect包下,一般主要涉及到以下兩個類:

    (1). Interface InvocationHandler:
            該接口中僅定義了一個方法Object:invoke(Object obj,Method method, J2EEjava語言JDK1.4APIjavalangObject.html">Object[] args)。在實際使用時,第一個參數obj一般是指代理類,method是被代理的方法,如上例中的request(),args為該方法的參數數組。這個抽象方法在代理類中動態實現。


    (2).Proxy:
            該類即為動態代理類,作用類似于上例中的ProxySubject,其中主要包含以下內容:

            Protected Proxy(InvocationHandler h):構造函數,估計用于給內部的h賦值。

            Static Class getProxyClass (ClassLoader loader, Class[] interfaces):獲得一個代理類,其中loader是類裝載器,interfaces是真實類所擁有的全部接口的數組。

            Static Object newProxyInstance(ClassLoader loader, Class[] interfaces, InvocationHandler h):返回代理類的一個實例,返回后的代理類可以當作被代理類使用(可使用被代理類的在Subject接口中聲明過的方法)。

           所謂Dynamic Proxy是這樣一種class:它是在運行時生成的class,在生成它時你必須提供一組interface給它,然后該class就宣稱它實現了這些 interface。你當然可以把該class的實例當作這些interface中的任何一個來用。當然啦,這個Dynamic Proxy其實就是一個Proxy,它不會替你作實質性的工作,在生成它的實例時你必須提供一個handler,由它接管實際的工作。

        在使用動態代理類時,我們必須實現InvocationHandler接口,以第一節中的示例為例:

     

           另外,如果要按照上述的方法使用代理模式,那么真實角色必須是事先已經存在的,并將其作為代理對象的內部屬性。但是實際使用時,一個真實角色必須對應一個代理角色,如果大量使用會導致類的急劇膨脹;此外,如果事先并不知道真實角色,該如何使用代理呢?這個問題可以通過Java的動態代理類來解決。


    抽象角色(之前是抽象類,此處應改為接口):

    public interface
     Subject

    {

        
    abstract public void
     request();

    }


    具體角色RealSubject:同上;


    代理角色:

    import java.lang.reflect.Method;

    import
     java.lang.reflect.InvocationHandler;


    public class DynamicSubject implements InvocationHandler 
    {

    private
     Object sub;


    public DynamicSubject() 
    {

    }



    public DynamicSubject(Object obj) {

        sub 
    =
     obj;

    }




    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {

        System.out.println(
    "before calling " +
     method);


        method.invoke(sub,args);


        System.out.println(
    "after calling " +
     method);

        
    return null
    ;

    }



    }



           該代理類的內部屬性為Object類,實際使用時通過該類的構造函數DynamicSubject(Object obj)對其賦值;此外,在該類還實現了invoke方法,該方法中的

    method.invoke(sub,args);

    其實就是調用被代理對象的將要被執行的方法,方法參數sub是實際的被代理對象,args為執行被代理對象相應操作所需的參數。通過動態代理類,我們可以在調用之前或之后執行一些相關操作。

    客戶端:

    import java.lang.reflect.InvocationHandler;

    import
     java.lang.reflect.Proxy;

    import
     java.lang.reflect.Constructor;

    import
     java.lang.reflect.Method;


    public class
     Client

    {


        
    static public void main(String[] args) throws
     Throwable

           
    {

          RealSubject rs 
    = new RealSubject(); //在這里指定被代理類


          InvocationHandler ds 
    = new DynamicSubject(rs); //初始化代理類

           Class cls 
    = rs.getClass();

          
    //以下是分解步驟


          
    /*

         Class c = Proxy.getProxyClass(cls.getClassLoader(),cls.getInterfaces()) ;

         Constructor ct=c.getConstructor(new Class[]{InvocationHandler.class});

         Subject subject =(Subject) ct.newInstance(new Object[]{ds});

         
    */


         
    //以下是一次性生成

          Subject subject 
    = (Subject) Proxy.newProxyInstance(cls.getClassLoader(),

                                     cls.getInterfaces(),ds );



          subject.request();

    }


    通過這種方式,被代理的對象(RealSubject)可以在運行時動態改變,需要控制的接口(Subject接口)可以在運行時改變,控制的方式(DynamicSubject)也可以動態改變,從而實現了非常靈活的動態代理關系(參見文獻2)。

    參考文獻:

    1.      閻宏,《Java 與模式》

    2.          透明,《動態代理的前世今生》

    3.   Forest Hou,Dynamic Proxy Java RMI 中的應用》


    posted on 2009-10-24 20:54 liyang 閱讀(249) 評論(0)  編輯  收藏 所屬分類: design pattern

    主站蜘蛛池模板: 久久久久亚洲AV成人无码| 在线永久免费的视频草莓| 日韩一级免费视频| 亚洲小说图区综合在线| 老司机在线免费视频| 亚洲综合激情五月色一区| 青青在线久青草免费观看| 激情内射亚洲一区二区三区爱妻| 国产成人午夜精品免费视频| 亚洲国产91在线| 成年女人永久免费观看片| 18禁亚洲深夜福利人口| 亚洲AⅤ永久无码精品AA| 一个人看的免费观看日本视频www 一个人看的免费视频www在线高清动漫 | 亚洲成a人片在线观看日本| baoyu116.永久免费视频| 久久亚洲AV午夜福利精品一区| 色欲A∨无码蜜臀AV免费播| 亚洲伊人久久大香线焦| 在线jyzzjyzz免费视频| 人妻仑乱A级毛片免费看| 波多野结衣免费一区视频 | 成人一a毛片免费视频| 看免费毛片天天看| 一本色道久久综合亚洲精品高清| 日韩精品无码免费专区网站| 亚洲成人动漫在线观看| 日韩在线看片免费人成视频播放| 成av免费大片黄在线观看| 亚洲国产精品成人精品小说| 国产成人免费片在线观看| 日本高清不卡aⅴ免费网站| 亚洲国产高清在线精品一区| 国产免费人人看大香伊| 久草视频在线免费看| 亚洲日韩中文字幕一区| 亚洲情综合五月天| 四虎国产精品免费久久| 精品国产污污免费网站入口| 亚洲av无码国产综合专区| 亚洲综合精品网站在线观看|