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方法。 */ } }