java動態代理--比較容易理解的例子

前幾天看到java的動態代理機制,不知道是啥玩意,而後看了看。死活不知道 
invoke(Object proxy, Method m, Object[] args)種的proxy是個什麼東西,放在這裏有什麼用?因而網上處處搜刮,把本身的理解寫了寫。 java

 

/** 
 * 相親接口 
 *  
 * @author zhengt 
 * @time Jun 3, 2095 3:13:03 PM 
 */  
public interface XiangQinInterface {  
    /** 
     * 相親方法 
     */  
    public void xiangQin();  
}  
/** 
 * 張三相親實現類 
 *  
 * @author zhengt 
 * @time Jun 3, 2095 3:14:48 PM 
 */  
public class ZhangSanXiangQinInterfaceImpl implements XiangQinInterface {  
    public void xiangQin() {  
        System.out.println("張三去相親,娶個漂亮老婆。");  
    }  
}  
import java.lang.reflect.InvocationHandler;  
import java.lang.reflect.Method;  
  
/** 
 * 相親但是一生的大事,相親前要準備一下,打扮得帥氣些。 
 *  
 * @author zhengt 
 * @time Jun 3, 2095 3:15:48 PM 
 */  
public class ReadyInvocationHandler implements InvocationHandler {  
    //相親接口的實現類,也就是張三相親類  
    private Object zhangSan = null;  
  
    public ReadyInvocationHandler(Object realSubject) {  
        this.zhangSan = realSubject;  
    }  
  
    public Object invoke(Object proxy, Method m, Object[] args) {  
        Object result = null;  
        try {  
            /** 
             * 動態代理類$Proxy0調用xiangQin方法時會調用它本身的xiangQin方法, 
             * 而它本身的xiangQin方法裏面調用的是super.h.invoke(this, , ),也就是父類Proxy的h的invoke方法, 
             * 也就是ReadyInvocationHandler類的invoke方法。 
             * 因此,invoke(Object proxy, Method m, Object[] args)種的proxy實際上就是動態代理類$Proxy0, 
             * 若是你將其強轉成XiangQinInterface而後調用它的xiangQin方法,而後它就會調用super.h.invoke(this, , ),這樣就會死循環。 
             */  
            /** 
             * 網上關於這裏最多問題就是Object proxy放在這裏用來作什麼呢?這個我也不知道, 
             * 不過至少咱們知道它究竟是個什麼東西,具體作什麼用嘛就不得而知了 
             */  
            System.out.println(proxy.getClass().getSimpleName());  
            System.out.println("張三相親前,代理人給他打扮了打扮。");  
            result = m.invoke(zhangSan, args);  
        } catch (Exception ex) {  
            System.exit(1);  
        }  
        return result;  
    }  
}  
import java.lang.reflect.InvocationHandler;  
import java.lang.reflect.Method;  
import java.lang.reflect.Proxy;  
  
/** 
 * 張三來到了婚介所(相親現場),開始相親。 
 *  
 * @author zhengt 
 * @time Jun 3, 2095 3:17:16 PM 
 */  
public class HunJieSuo {  
    public static void main(String args[]) {  
        //先將張三相親這個相親的實現類實例化,也就是獲得XiangQinInterface接口的一個實例對象  
        XiangQinInterface zhangSan = new ZhangSanXiangQinInterfaceImpl();  
        /** 
         * 獲得ZhangSanXiangQinInterfaceImpl這個類的一個代理類,同時爲代理類綁定了一個處理類ReadyInvocationHandler。 
         * 聽着很繞口,其實就是每次調用ZhangSanXiangQinInterfaceImpl這個子類的xiangQin方法時, 
         * 不是zhangSan這個ZhangSanXiangQinInterfaceImpl類的實例去調用, 
         * 而是這個ZhangSanXiangQinInterfaceImpl的代理類ReadyInvocationHandler去調用它本身的invoke方法, 
         * 這個invoke方法裏呢能夠調用zhangSan這個實例的xiangQin方法 
         */  
        /** 
         * 在java種怎樣實現動態代理呢 
         * 第一步,咱們要有一個接口,還要有一個接口的實現類,而這個實現類呢就是咱們要代理的對象, 
         * 所謂代理呢也就是在調用實現類的方法時,能夠在方法執行先後作額外的工做,這個就是代理。 
         * 第二步,咱們要本身寫一個在要代理類的方法執行時,可以作額外工做的類,而這個類必須繼承InvocationHandler接口, 
         * 爲何要繼承它呢?由於代理類的實例在調用實現類的方法的時候,不會調真正的實現類的這個方法, 
         * 而是轉而調用這個類的invoke方法(繼承時必須實現的方法),在這個方法中你能夠調用真正的實現類的這個方法。 
         * 第三步,在要用代理類的實例去調用實現類的方法的時候,寫出下面兩段代碼。 
         */  
        XiangQinInterface proxy = (XiangQinInterface) Proxy.newProxyInstance(  
                zhangSan.getClass().getClassLoader(),  
                zhangSan.getClass().getInterfaces(),  
                new ReadyInvocationHandler(zhangSan));  
        proxy.xiangQin();  
        /** 
         * 這裏要解釋下中部那段長長的代碼的意思,以及具體作了哪些工做? 
         * 第一,根據zhangSan.getClass().getClassLoader()這個要代理類的類加載器和 
         * zhangSan.getClass().getInterfaces()要代理類所實現的全部的接口 
         * 做爲參數調用Proxy.getProxyClass(ClassLoader loader, Class<?>... interfaces) 
         * 的方法返回代理類的java.lang.Class對象,也就是獲得了java動態生成的代理類$Proxy0的Class對象。 
         * 同時,java還讓這個動態生成的$Proxy0類實現了要代理類的實現的全部接口,並繼承了Proxy接口。 
         * 第二,實例化這個動態生成的$Proxy0類的一個實例,實例化代理類的構造函數爲Proxy(InvocationHandler h), 
         * 也就是說要實例化這個動態生成的$Proxy0類,必須給它一個InvocationHandler參數,也就是咱們本身實現的用來在代理類 
         * 方法執行先後作額外工做的類ReadyInvocationHandler。 
         * 這段代碼Proxy.newProxyInstance(zhangSan.getClass().getClassLoader(),zhangSan.getClass().getInterfaces(),new ReadyInvocationHandler(zhangSan)) 
         * 獲得的實際上是一個類名叫$Proxy0 extends Proxy implements XiangQinInterface的類。 
         * 第三,將這個$Proxy0類強制轉型成XiangQinInterface類型,調用xiangQin方法。 
         */  
    }  
}
相關文章
相關標籤/搜索