亚洲免费在线-亚洲免费在线播放-亚洲免费在线观看-亚洲免费在线观看视频-亚洲免费在线看-亚洲免费在线视频

動態代理 Proxy InvocationHandler學習

系統 1582 0

?參考?http://www.iteye.com/topic/683613

參考?http://hi.baidu.com/malecu/item/9e0edc115cb597a1feded5a0

參考 http://www.educity.cn/wenda/360356.html

參考?http://langyu.iteye.com/blog/410071

?

      /**
 * 相親接口
 * 
 * @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方法(繼承時必須實現的方法),在這個方法中你可以調用真正的實現類的這個方法。
		 * 第三步,在要用代理類的實例去調用實現類的方法的時候,寫出下面兩段代碼。
		 */
 // 獲得代理類($Proxy0 extends Proxy implements XiangQinInterface)的實例.
		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方法。
		 */
	}
}

    

?

備注:著重看“ // 獲得代理類($Proxy0 extends Proxy implements XiangQinInterface)的實例. ”這個注解 。?

? 動態代理 Proxy InvocationHandler學習


?一.相關類及其方法:

java.lang.reflect.Proxy,

Proxy 提供用于創建動態代理類和實例的靜態方法 .

newProxyInstance()

返回一個指定接口的代理類實例,該接口可以將方法調用指派到指定的調用處理程序

(詳見api文檔)

?

java.lang.reflect.InvocationHandler,

InvocationHandler 是代理實例的調用處理程序 實現的接口 。?

invoke()

在代理實例上處理方法調用并返回結果。在與方法關聯的代理實例上調用方法時,將在調用處理程序上調用此方法。

?

創建某一接口 Foo 的代理:?

?

      InvocationHandler handler = new MyInvocationHandler(...);
Class proxyClass = Proxy.getProxyClass(
    Foo.class.getClassLoader(), new Class[] { Foo.class });
Foo f = (Foo) proxyClass.
    getConstructor(new Class[] { InvocationHandler.class }).
    newInstance(new Object[] { handler });
    

?

?

或使用以下更簡單的方法:?

?

      Foo f = (Foo) Proxy.newProxyInstance(Foo.class.getClassLoader(),
                                          new Class[] { Foo.class },
                                          handler);
    

?

?

四.機制分析:

Proxy.(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h)做了以下幾件事.

(1)根據參數loader和interfaces調用方法 getProxyClass(loader, interfaces)創建代理類$Proxy.

$Proxy0類實現了interfaces的接口,并繼承了Proxy類.

?

(2)實例化$Proxy0并在構造方法中把BusinessHandler傳過去,接著$Proxy0調用父類Proxy的構造器,為h賦值,如下:

      class Proxy{
   InvocationHandler h=null;
   protected Proxy(InvocationHandler h) {
    this.h = h;
   }
   ...
}
    

?

?

下面是本例的$Proxy0類的源碼(好不容易才把它提出來):

?

      import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.lang.reflect.UndeclaredThrowableException;
public final class $Proxy0 extends Proxy implements 
      
        XiangQinInterface 
      
      
        {
      
      
private static Method m1;
private static Method m0;
private static Method m3;
private static Method m2;

static {
   try {
    m1 = Class.forName("java.lang.Object").getMethod("equals",
      new Class[] { Class.forName("java.lang.Object") });
    m0 = Class.forName("java.lang.Object").getMethod("hashCode",
      new Class[0]);
    m3 = Class.forName("com.ml.test.Manager").getMethod("modify",
      new Class[0]);
    m2 = Class.forName("java.lang.Object").getMethod("toString",
      new Class[0]);
   } catch (NoSuchMethodException nosuchmethodexception) {
    throw new NoSuchMethodError(nosuchmethodexception.getMessage());
   } catch (ClassNotFoundException classnotfoundexception) {
    throw new NoClassDefFoundError(classnotfoundexception.getMessage());
   }
}

public $Proxy0(InvocationHandler invocationhandler) {
   super(invocationhandler);
}
@Override
public final boolean equals(Object obj) {
   try {
    return ((Boolean) super.h.invoke(this, m1, new Object[] { obj }))
      .booleanValue();
   } catch (Throwable throwable) {
    throw new UndeclaredThrowableException(throwable);
   }
}
@Override
public final int hashCode() {
   try {
    return ((Integer) super.h.invoke(this, m0, null)).intValue();
   } catch (Throwable throwable) {
    throw new UndeclaredThrowableException(throwable);
   }
}
public final void modify() {
   try {
    super.h.invoke(this, m3, null);
    return;
   } catch (Error e) {
   } catch (Throwable throwable) {
    throw new UndeclaredThrowableException(throwable);
   }
}
@Override
public final String toString() {
   try {
    return (String) super.h.invoke(this, m2, null);
   } catch (Throwable throwable) {
    throw new UndeclaredThrowableException(throwable);
   }
}
}
    

?

?

?

接著把得到的$Proxy0實例強制轉換成XiangQinInterface?.

當執行proxy.xiangQin()方法時,就調用了$Proxy0類中的xiangQin()方法.

在modify方法中,調用父類Proxy中的h的invoke()方法.

即InvocationHandler.invoke();?

動態代理 Proxy InvocationHandler學習


更多文章、技術交流、商務合作、聯系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號聯系: 360901061

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。

【本文對您有幫助就好】

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描上面二維碼支持博主2元、5元、10元、自定義金額等您想捐的金額吧,站長會非常 感謝您的哦!!!

發表我的評論
最新評論 總共0條評論
主站蜘蛛池模板: 美国免费三片在线观看 | 手机在线中文字幕 | 一个色在线| 狠久久 | 国语毛片| 日本亚洲a| 中文日韩欧美 | 亚洲免费一| 国产精品欧美亚洲韩国日本 | 久久思re热9一区二区三区 | 国产精品一区在线免费观看 | 国产成人啪精品视频免费网 | 欧美jizzhd欧美巨大 | 久久精彩免费视频 | 色涩在线| 成人亚洲欧美 | 91视频香蕉 | 亚洲欧美精品天堂久久综合一区 | 91在线视频在线观看 | 欧美日韩国产另类一区二区三区 | 久久精品国产2020观看福利色 | 亚欧精品在线观看 | 国产免费一区二区三区在线 | 日韩欧美亚洲综合久久影院d3 | 久久久国产亚洲精品 | 一级爱爱片一级毛片-一毛 一级白嫩美女毛片免费 | 黄色影院在线观看视频 | 色婷婷久久综合中文久久一本` | 亚洲一级毛片免费看 | 夜夜爽天天狠狠九月婷婷 | 国产99视频精品免费视频7 | 天堂国产 | 久久精品国产2020观看福利色 | 色综合色综合色综合色综合网 | 一区二区福利视频 | 成人短视频在线观看免费 | 大乳女做爰中文字幕 | 国产成人免费高清视频 | 四虎国产精品免费久久影院 | 一区国严二区亚洲三区 | 免费观看一级成人毛片软件 |