一区二区三区日韩精品-日韩经典一区二区三区-五月激情综合丁香婷婷-欧美精品中文字幕专区

分享

java動態(tài)代理模式初解

 yfm10 2010-03-20
  java動態(tài)代理模式初解 收藏
第一部分
1.代理模式的作用和定義: 為其他對象提供一種代理以控制對這個對象的訪問。在某些情況下,一個客戶不想或者不能直接引用另一個對象,而代理對象可以在客戶端和目標(biāo)對象之間起到中介的作用。
 2.代理模式中涉及的角色
  抽象角色:聲明真實對象和代理對象的共同接口;一般聲明為抽象類或是接口.
 代理角色:代理對象角色內(nèi)部含有對真實對象的引用,從而可以操作真實對象,同時代理對象提供與真實對象相同的接口以便在任何時刻都能代替真實對象。同時,代理對象可以在執(zhí)行真實對象操作時,附加其他的操作,相當(dāng)于對真實對象進(jìn)行封裝。
 真實角色:代理角色所代表的真實對象,是我們最終要引用的對象。
3.針對三種角色舉個例子
抽象角色
package proxypattern;
public interface Subject ...{
 
    public void dothing();
}
真實角色,實現(xiàn)了Subject 的dothing()方法;
package proxypattern;
public class RealSubject implements Subject...{
   public RealSubject()...{
    
   }
 
   public void dothing()...{
       System.out.println("Do you want do.");
   }
}代理角色:
  
package proxypattern;
public class ProxySubject implements Subject...{
   
    public RealSubject realSubject;
    public ProxySubject()...{
       
    }
   
    public void dothing()...{
        predothing();
        if(realSubject==null)...{
            realSubject=new RealSubject();
        }
        realSubject.dothing();  //執(zhí)行真實對象的dothing()方法
        afterdothing();
    }
   
    private void predothing()...{
        System.out.println("before you do thing!");
    }
    private void afterdothing()...{
        System.out.println("after you do thing!");
    }
}                                                                                                                                                                                          
  測試事例              
package proxypattern;
public class ProxyTest ......{
    /** *//** *//** *//**
     * @param args
     */
    public static void main(String[] args) ......{
       
        Subject sub=new ProxySubject();
        sub.dothing();
    }
}4.如果要按照上述的方法使用代理模式,那么真實角色必須是事先已經(jīng)存在的,并將其作為代理對象的內(nèi)部屬性。但是實際使用時,一個真實角色必須對應(yīng)一個代理角色,如果大量使用會導(dǎo)致類的急劇膨脹;此外,如果事先并不知道真實角色,該如何使用代理呢?這個問題可以通過Java的動態(tài)代理類來解決5.如果要按照上述的方法使用代理模式,那么真實角色必須是事先已經(jīng)存在的,并將其作為代理對象的內(nèi)部屬性。但是實際使用時,一個真實角色必須對應(yīng)一個代理角色,如果大量使用會導(dǎo)致類的急劇膨脹;此外,如果事先并不知道真實角色,該如何使用代理呢?這個問題可以通過Java的動態(tài)代理類來解決
第二部分
.動態(tài)代理類
Java動態(tài)代理類位于Java.lang.reflect包下,一般主要涉及到以下兩個類:
(1). Interface InvocationHandler:該接口中僅定義了一個方法Object:invoke(Object obj,Method method, Object[] args)。在實際使用時,第一個參數(shù)obj一般是指代理類,method是被代理的方法,如上例中的dothing(),args為該方法的參數(shù)數(shù)組。 這個抽象方法在代理類中動態(tài)實現(xiàn)。

(2).Proxy:該類即為動態(tài)代理類,作用類似于上例中的ProxySubject,其中主要包含以下內(nèi)容:
Protected Proxy(InvocationHandler h):構(gòu)造函數(shù),估計用于給內(nèi)部的h賦值。
Static Class getProxyClass (ClassLoader loader, Class[] interfaces):獲得一個代理類,其中l(wèi)oader是類裝載器,interfaces是真實類所擁有的全部接口的數(shù)組。
Static Object newProxyInstance(ClassLoader loader, Class[] interfaces, InvocationHandler h):返回代理類的一個實例,返回后的代理類可以當(dāng)作被代理類使用(可使用被代理類的在Subject接口中聲明過的方法)。
 
所謂Dynamic Proxy是這樣一種class:它是在運行時生成的class,在生成它時你必須提供一組interface給它,然后該class就宣稱它實現(xiàn)了這些 interface。你當(dāng)然可以把該class的實例當(dāng)作這些interface中的任何一個來用。當(dāng)然啦,這個Dynamic Proxy其實就是一個Proxy,它不會替你作實質(zhì)性的工作,在生成它的實例時你必須提供一個handler,由它接管實際的工作。
代理角色
package dynamicproxy;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
public class DynamicSubject implements InvocationHandler ...{
   
public DynamicSubject() ...{
       
       
    }
   
    public DynamicSubject(Object obj) ...{
       
        sub = obj;
    }
   
    private Object sub;
    public Object invoke(Object proxy, Method method, Object[] args)
            throws Throwable ...{
        // TODO Auto-generated method stub
        System.out.println("before you do thing");
        method.invoke(sub, args);
        System.out.println("after you do thing");
        return null;
    }
 
}
該代理類的內(nèi)部屬性為Object類,實際使用時通過該類的構(gòu)造函數(shù)DynamicSubject(Object obj)對其賦值;此外,在該類還實現(xiàn)了invoke方法,該方法中的
method.invoke(sub,args);
其實就是調(diào)用被代理對象的將要被執(zhí)行的方法,方法參數(shù)sub是實際的被代理對象,args為執(zhí)行被代理對象相應(yīng)操作所需的參數(shù)。通過動態(tài)代理類,我們可以在調(diào)用之前或之后執(zhí)行一些相關(guān)操作。
調(diào)用事例
package dynamicproxy;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Proxy;
import proxypattern.RealSubject;
import proxypattern.Subject;
public class Client ...{
    /** *//**
     * @param args
     */
    public static void main(String[] args) throws Throwable...{
        // TODO Auto-generated method stub
         RealSubject rs=new RealSubject();
         InvocationHandler ds=new DynamicSubject(rs);
         Class cls=rs.getClass();
         Subject subject=(Subject)Proxy.newProxyInstance(cls.getClassLoader(),cls.getInterfaces(),ds);
         subject.dothing();
    }
}
通過這種方式,被代理的對象(RealSubject)可以在運行時動態(tài)改變,需要控制的接口(Subject接口)可以在運行時改變,控制的方式(DynamicSubject類)也可以動態(tài)改變,從而實現(xiàn)了非常靈活的動態(tài)代理關(guān)系。
cglib

cglib實現(xiàn)AOP
CGLib 與java標(biāo)準(zhǔn)庫提供的實現(xiàn)方案不同,cglib主要是基于實現(xiàn)類(如StudentInfoServiceImpl.java)擴展一個子類 來實現(xiàn)。與Dynamic Proxy中的Proxy和InvocationHandler相對應(yīng),net.sf.cglib.proxy.Enhancer和 MethodInterceptor在CGLib中負(fù)責(zé)完成代理對象創(chuàng)建和方法截獲處理,產(chǎn)生的是目標(biāo)類的子類而不是通過接口來實現(xiàn)方法攔截的, Enhancer主要是用于構(gòu)造動態(tài)代理子類來實現(xiàn)攔截,MethodInterceptor(擴展了Callback接口)主要用于實現(xiàn)around advice(AOP中的概念):
1)我們的業(yè)務(wù)處理(StudentInfoServiceImpl.java):
public class StudentInfoServiceImpl{
 public void findInfo(String name){
  System.out.println("你目前輸入的名字是:"+name);
 }
}
     2)實行一個工具來處理日志功能(AOPInstrumenter.java):
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodProxy;
import java.lang.reflect.Method;
import org.apache.log4j.Logger;
public class AOPInstrumenter implements MethodInterceptor{
 private Logger log=Logger.getLogger(AOPInstrumenter.class);
 private Enhancer enhancer=new Enhancer();
 
 public Object getInstrumentedClass(Class clz){
  enhancer.setSuperclass(clz);
  enhancer.setCallback(this);
  return enhancer.create();
 }
 
 public Object intercept(Object o,Method method,Object[] args,MethodProxy proxy) throws Throwable{
  log.info("調(diào)用日志方法"+method.getName());
  Object result=proxy.invokeSuper(o,args);
  return result;
 }
 
}
     3)我們來測試一下(AOPTest.java):
public class AOPTest{
 public static void main(String[] args){
  AOPInstrumenter instrumenter=new AOPInstrumenter();
  StudentInfoServiceImpl studentInfo=(StudentInfoServiceImpl)instrumenter.getInstrumentedClass(StudentInfoServiceImpl.class);
  studentInfo.findInfo("阿飛");
 }
}
   輸出結(jié)果與以上相同。
 CGLib中為實現(xiàn)以上目的,主要提供的類
1)Enhancer:setCallback(Callback) ,setSuperclass(Class) ,create()返回動態(tài)子類Object
2)MethodInterceptor必須實現(xiàn)的接口:intercept(Object,Method,Object[],MethodProxy)返回的是原方法調(diào)用的結(jié)果。和Proxy原理一樣。

本文來自CSDN博客,轉(zhuǎn)載請標(biāo)明出處:http://blog.csdn.net/oscar999/archive/2007/08/03/1724039.aspx

    本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點。請注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊一鍵舉報。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多

    美女被后入福利在线观看| 白丝美女被插入视频在线观看| 国产av精品一区二区| 亚洲少妇一区二区三区懂色| 国产日韩综合一区在线观看| 久久精品国产99精品最新| 国产在线一区二区三区不卡| 午夜精品在线视频一区| 在线视频免费看你懂的| 欧美又大又黄刺激视频| 久久99夜色精品噜噜亚洲av | 久久精品免费视看国产成人| 亚洲欧美国产中文色妇| 日韩精品区欧美在线一区| 欧美精品中文字幕亚洲| 亚洲中文字幕亲近伦片| 亚洲国产综合久久天堂| 国产精品日韩欧美第一页| 国产精品一区二区丝袜| 国产综合一区二区三区av | 日韩欧美国产精品中文字幕| 日韩高清一区二区三区四区| 亚洲综合色婷婷七月丁香| 成人国产一区二区三区精品麻豆| 国产91人妻精品一区二区三区 | 欧美有码黄片免费在线视频| 亚洲免费黄色高清在线观看| 亚洲综合日韩精品欧美综合区 | 亚洲五月婷婷中文字幕| 国产欧美亚洲精品自拍| 中文字幕在线区中文色| 国产色第一区不卡高清| 日韩精品中文字幕在线视频| 人妻少妇av中文字幕乱码高清| 国产一区二区三中文字幕| 日韩特级黄色大片在线观看| 最新69国产精品视频| 欧美日韩精品久久亚洲区熟妇人| 二区久久久国产av色| 精品精品国产欧美在线| 九九久久精品久久久精品|