Java Proxy

前幾天看到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方法。
		 */
	}
}
相關文章
相關標籤/搜索