[轉]深入理解Java Proxy機制

來源:互聯網
上載者:User

標籤:

該文章轉自網路,原文不可考,給出轉載文章連結:http://blog.csdn.net/rokii/article/details/4046098

 

看項目代碼看到一段寫的很美的代理機制,整理一下:

  動態代理其實就是java.lang.reflect.Proxy類動態根據您指定的所有介面產生一個class byte,該class會繼承Proxy類,並實現所有你指定的介面(您在參數中傳入的介面數組);然後再利用您指定的classloader將 class byte載入進系統,最後產生這樣一個類的對象,並初始化該對象的一些屬性,如invocationHandler,以及所有的介面對應的Method成員。 初始化之後將對象返回給調用的用戶端。這樣用戶端拿到的就是一個實現你所有的介面的Proxy對象。請看執行個體分析:

 

業務介面

public interface BusinessProcessor { public void processBusiness();}

 

業務介面實作類別

public class BusinessProcessorImpl implements BusinessProcessor {   public void processBusiness() {    System.out.println("processing business.....");   }}

 

業務代理類

import java.lang.reflect.InvocationHandler;import java.lang.reflect.Method;public class BusinessProcessorHandler implements InvocationHandler {   private Object target = null;    BusinessProcessorHandler(Object target){    this.target = target;   }    public Object invoke(Object proxy, Method method, Object[] args)     throws Throwable {    System.out.println("You can do something here before process your business");    Object result = method.invoke(target, args);    System.out.println("You can do something here after process your business");    return result;   }}

 

用戶端應用類

import java.lang.reflect.Field;import java.lang.reflect.Method;import java.lang.reflect.Modifier;import java.lang.reflect.Proxy;public class Test { public static void main(String[] args) {
  BusinessProcessorImpl bpimpl = new BusinessProcessorImpl();
  BusinessProcessorHandler handler = new BusinessProcessorHandler(bpimpl);
  BusinessProcessor bp = (BusinessProcessor)Proxy.newProxyInstance(bpimpl.getClass().getClassLoader(), bpimpl.getClass().getInterfaces(), handler);  bp.processBusiness(); }}

列印結果:

You can do something here before process your business
processing business.....
You can do something here after process your business

 通過結果我們就能夠很簡單的看出Proxy的作用了,它能夠在你的核心業務方法前後做一些你所想做的輔助工作,如log日誌,安全機制等等。

 

現在我們來分析一下上面的類的工作原理。

類一二沒什麼好說的。

先看看類三吧:實現了InvocationHandler介面的invoke方法。其實這個類就是最終Proxy調用的固定介面方法。Proxy不管用戶端的業務方法是怎麼實現的。當用戶端調用Proxy時,它只

會調用InvocationHandler的invoke介面,所以我們的真正實現的方法就必須在invoke方法中去調用。關係如下:

 BusinessProcessorImpl bpimpl = new BusinessProcessorImpl();
 BusinessProcessorHandler handler = new BusinessProcessorHandler(bpimpl);

BusinessProcessor bp = (BusinessProcessor)Proxy.newProxyInstance(....);

bp.processBusiness()-->invocationHandler.invoke()-->bpimpl.processBusiness();

那麼bp到底是怎麼樣一個對象呢。我們改一下main方法看一下就知道了:

public static void main(String[] args) {  BusinessProcessorImpl bpimpl = new BusinessProcessorImpl();  BusinessProcessorHandler handler = new BusinessProcessorHandler(bpimpl);  BusinessProcessor bp = (BusinessProcessor)Proxy.newProxyInstance(bpimpl.getClass().getClassLoader(), bpimpl.getClass().getInterfaces(), handler);  bp.processBusiness();  System.out.println(bp.getClass().getName()); }

 

輸出結果:

You can do something here before process your business
processing business.....
You can do something here after process your business
$Proxy0

 bp原來是個$Proxy0這個類的對象。那麼這個類到底是長什麼樣子呢?好的。我們再寫二個方法去把這個類列印出來看個究竟,是什麼三頭六臂呢?我們在main下面寫如下兩個靜態方法。

public static String getModifier(int modifier){  String result = "";  switch(modifier){   case Modifier.PRIVATE:    result = "private";   case Modifier.PUBLIC:    result = "public";   case Modifier.PROTECTED:    result = "protected";   case Modifier.ABSTRACT :    result = "abstract";   case Modifier.FINAL :    result = "final";   case Modifier.NATIVE :    result = "native";   case Modifier.STATIC :    result = "static";   case Modifier.SYNCHRONIZED :    result = "synchronized";   case Modifier.STRICT  :    result = "strict";   case Modifier.TRANSIENT :    result = "transient";   case Modifier.VOLATILE :    result = "volatile";   case Modifier.INTERFACE :    result = "interface";  }  return result; }  public static void printClassDefinition(Class clz){    String clzModifier = getModifier(clz.getModifiers());  if(clzModifier!=null && !clzModifier.equals("")){   clzModifier = clzModifier + " ";  }  String superClz = clz.getSuperclass().getName();  if(superClz!=null && !superClz.equals("")){   superClz = "extends " + superClz;  }    Class[] interfaces = clz.getInterfaces();    String inters = "";  for(int i=0; i<interfaces.length; i++){   if(i==0){    inters += "implements ";   }   inters += interfaces[i].getName();  }    System.out.println(clzModifier +clz.getName()+" " + superClz +" " + inters );  System.out.println("{");    Field[] fields = clz.getDeclaredFields();  for(int i=0; i<fields.length; i++){   String modifier = getModifier(fields[i].getModifiers());   if(modifier!=null && !modifier.equals("")){    modifier = modifier + " ";   }   String fieldName = fields[i].getName();   String fieldType = fields[i].getType().getName();   System.out.println("    "+modifier + fieldType + " "+ fieldName + ";");  }    System.out.println();    Method[] methods = clz.getDeclaredMethods();  for(int i=0; i<methods.length; i++){   Method method = methods[i];   String modifier = getModifier(method.getModifiers());   if(modifier!=null && !modifier.equals("")){    modifier = modifier + " ";   }      String methodName = method.getName();      Class returnClz = method.getReturnType();   String retrunType = returnClz.getName();      Class[] clzs = method.getParameterTypes();   String paraList = "(";   for(int j=0; j<clzs.length; j++){    paraList += clzs[j].getName();    if(j != clzs.length -1 ){     paraList += ", ";    }   }   paraList += ")";      clzs = method.getExceptionTypes();   String exceptions = "";   for(int j=0; j<clzs.length; j++){    if(j==0){     exceptions += "throws ";    }    exceptions += clzs[j].getName();        if(j != clzs.length -1 ){     exceptions += ", ";    }   }      exceptions += ";";      String methodPrototype = modifier +retrunType+" "+methodName+paraList+exceptions;      System.out.println("    "+methodPrototype );     }  System.out.println("}"); }
View Code

 

再改寫main方法

 public static void main(String[] args) {  BusinessProcessorImpl bpimpl = new BusinessProcessorImpl();  BusinessProcessorHandler handler = new BusinessProcessorHandler(bpimpl);  BusinessProcessor bp = (BusinessProcessor)Proxy.newProxyInstance(bpimpl.getClass().getClassLoader(), bpimpl.getClass().getInterfaces(), handler);  bp.processBusiness();  System.out.println(bp.getClass().getName());  Class clz = bp.getClass();  printClassDefinition(clz); }

 

 

現在我們再看看輸出結果:

You can do something here before process your business
processing business.....
You can do something here after process your business
$Proxy0
$Proxy0 extends java.lang.reflect.Proxy implements com.tom.proxy.dynamic.BusinessProcessor
{
    java.lang.reflect.Method m4;
    java.lang.reflect.Method m2;
    java.lang.reflect.Method m0;
    java.lang.reflect.Method m3;
    java.lang.reflect.Method m1;

    void processBusiness();
    int hashCode();
    boolean equals(java.lang.Object);
    java.lang.String toString();
}

很明顯,Proxy.newProxyInstance方法會做如下幾件事:

1,根據傳入的第二個參數interfaces動態產生一個類,實現interfaces中的介面,該例中即BusinessProcessor介面的processBusiness方法。並且繼承了Proxy類,重寫了hashcode,toString,equals等三個方法。具體實現可參看 ProxyGenerator.generateProxyClass(...); 該例中產生了$Proxy0類

2,通過傳入的第一個參數classloder將剛產生的類載入到jvm中。即將$Proxy0類load

3,利用第三個參數,調用$Proxy0的$Proxy0(InvocationHandler)建構函式 建立$Proxy0的對象,並且用interfaces參數遍曆其所有介面的方法,並產生Method對象初始化對象的幾個Method成員變數

4,將$Proxy0的執行個體返回給用戶端。

現在好了。我們再看用戶端怎麼調就清楚了。

1,用戶端拿到的是$Proxy0的執行個體對象,由於$Proxy0繼承了BusinessProcessor,因此轉化為BusinessProcessor沒任何問題。

BusinessProcessor bp = (BusinessProcessor)Proxy.newProxyInstance(....);

2,bp.processBusiness();

實際上調用的是$Proxy0.processBusiness();那麼$Proxy0.processBusiness()的實現就是通過InvocationHandler去調用invoke方法啦!

 

[轉]深入理解Java Proxy機制

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.