程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> JAVA編程 >> JAVA綜合教程 >> Java:靜態代理and動態代理,java靜態and動態

Java:靜態代理and動態代理,java靜態and動態

編輯:JAVA綜合教程

Java:靜態代理and動態代理,java靜態and動態


代理模式是常用的設計模式,其特征是代理類與委托類具有相同的接口,在具體實現上,有靜態代理和動態代理之分。代理類與委托類之間通常會存在關聯關系,一個代理類的對象與一個委托類的對象關聯,代理類的對象本身並不真正實現服務,而是通過調用委托類的對象的相關方法,來提供特定的服務,也就是說代理類主要負責為委托類預處理消息、過濾消息、把消息轉發給委托類,以及事後處理消息等。

靜態代理和動態代理的一個顯著區別:

靜態代理:由程序員創建或特定工具自動生成源代碼,再對其編譯。在程序運行前,代理類的.class文件就已經存在了。 
動態代理:動態代理類的字節碼在程序運行時由Java反射機制動態生成,無需程序員手工編寫它的源代碼。

 

靜態代理:

 

動態代理:

 

JDK動態代理解說:

java.lang.reflect包中的InvocationHandler接口和Proxy類提供了生成動態代理類的能力。

(1)InvocationHandler接口:

public interface InvocationHandler { 
    public Object invoke(Object proxy,Method method,Object[] args) throws Throwable; 
}

參數說明: 
  Object proxy:指被代理的對象。 
  Method method:要調用的方法 
  Object[] args:方法調用時所需要的參數

可以將InvocationHandler接口的子類想象成一個代理的最終操作類,如上例中的定義的LogHandler類。

 

(2)Proxy類:

Proxy類是專門完成代理的操作類,可以通過此類為一個或多個接口動態地生成實現類,此類提供了如下的操作方法:

public static Object newProxyInstance(ClassLoader loader,
                                          Class<?>[] interfaces,
                                          InvocationHandler h)
        throws IllegalArgumentException
    {
        if (h == null) {
            throw new NullPointerException();
        }

        /*
         * Look up or generate the designated proxy class.
         */
        Class<?> cl = getProxyClass(loader, interfaces);

        /*
         * Invoke its constructor with the designated invocation handler.
         */
        try {
            Constructor cons = cl.getConstructor(constructorParams);
            return cons.newInstance(new Object[] { h });
        } catch (NoSuchMethodException e) {
            throw new InternalError(e.toString());
        } catch (IllegalAccessException e) {
            throw new InternalError(e.toString());
        } catch (InstantiationException e) {
            throw new InternalError(e.toString());
        } catch (InvocationTargetException e) {
            throw new InternalError(e.toString());
        }
    }

參數說明: 
  ClassLoader loader:類加載器 
  Class<?>[] interfaces:得到全部的接口 
  InvocationHandler h:得到InvocationHandler接口的子類實例

 

參看下面這篇文章中作者對上述源碼的分析

【原創】JDK動態代理,此次之後,永生難忘。  http://www.cnblogs.com/dreamroute/p/5273888.html

徹底理解JAVA動態代理  http://www.cnblogs.com/flyoung2008/p/3251148.html 

 

擴展:

JDK的動態代理依靠接口實現,如果有些類並沒有實現接口,則不能使用JDK代理。

Spring AOP有兩種方式實現動態代理,如果基於接口編程,默認是JDK動態代理,否則就是cglib方式,另外spring的配置文件裡面也可以設置使用cglib來做動態代理。cglib的原理是對指定的目標類生成一個子類,並覆蓋其中方法實現增強,但因為采用的是繼承,所以不能對final修飾的類進行代理。

注:此部分需查看cglib實現方式

 

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved