生活随笔
收集整理的這篇文章主要介紹了
如何使用Proxy模式及Java内建的动态代理机制
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
http://zhangjunhd.blog.51cto.com/113473/69996
1.Proxy模式 代理模式支持將某些操作從實際的對象中分離出來,通過它的代理類提供處理。這樣便于修改和管理這些特定的操作。 下面示例一個代理模式的實現。 <!--[if !vml]-->
<!--[endif]--> <<interface>>Subject.java
package com.zj.proxy; public interface Subject { ??? void operation1(); ??? ??? void operation2(String arg); }
現實類RealSubject.java
package com.zj.proxy; public class RealSubject implements Subject { ??? public void operation1() { ?????? System.out .println( "Realer do operation1" ); ??? } ??? public void operation2(String arg) { ?????? System.out .println( "Realer do operation2 with " + arg); ??? } }
代理類ProxySubject.java
package com.zj.proxy; public class ProxySubject implements Subject { ??? private Subject proxied ; // 被代理對象 ??? public ProxySubject(Subject proxied) { ?????? this . proxied = proxied; ??? } ??? public void operation1() { ?????? System.out .println( "Proxyer do operation1" ); ?????? proxied .operation1(); ??? } ??? public void operation2(String arg) { ?????? System.out .println( "Proxyer do operation2 with " + arg); ?????? proxied .operation2(arg); ??? } }
測試類
SimpleProxyDemo.java package com.zj.proxy.client; import com.zj.proxy.Subject; import com.zj.proxy.RealSubject; import com.zj.proxy.ProxySubject; public class SimpleProxyDemo { ??? public static void consumer( Subject subject) { ?????? subject.operation1(); ?????? subject.operation2("ZJ" ); ??? } ??? public static void main(String[] args) { ?????? RealSubject real = new RealSubject(); ?????? System.out .println( "===Without Proxy===" ); ?????? consumer(real); ?????? System.out .println( "===Use Proxy===" ); ?????? consumer(new ProxySubject(real)); ??? } }
結果:
===Without Proxy=== Realer do operation1 Realer do operation2 with ZJ ===Use Proxy=== Proxyer do operation1 Realer do operation1 Proxyer do operation2 with ZJ Realer do operation2 with ZJ 2.使用Java的動態代理機制 設計一個類用于實現InvocationHandle接口,InvocationHandler 是代理實例的調用處理程序實現的接口。 每個代理實例都具有一個關聯的調用處理程序。對代理實例調用方法時,將對方法調用進行編碼并將其指派到它的調用處理程序的 invoke 方法。 <<interface>>InvocationHandle.java
package java.lang.reflect; public interface InvocationHandler { ??? public Object invoke(Object proxy, Method method, Object[] args) ??? throws Throwable; }
對應invoke參數: [1]proxy - 在其上調用方法的代理實例; [2]method - 對應于在代理實例上調用的接口方法的 Method 實例; [3]args - 包含傳入代理實例上方法調用的參數值的對象數組,如果接口方法不使用參數,則為 null。 現在設計一個類實現該接口,并提供代理實例。
DynamicProxyHandler.java package com.zj.proxy.dynamic; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; public class DynamicProxyHandler implements InvocationHandler { ??? private Object proxied ; ??? public DynamicProxyHandler(Object proxied) { ?????? this . proxied = proxied; ??? } ??? public Object invoke(Object proxy, Method method, Object[] args) ?????????? throws Throwable { ?????? System.out .println( "**** proxy: ****\n" + proxy.getClass() ????????????? + "\nmethod: " + method + "\nargs: " + args); ?????? if (args != null ) ?????????? for (Object arg : args) ????????????? System.out .println( "? " + arg); ?????? return method.invoke( proxied , args); ??? } }
這里的
private Object proxied ; 即代理實例,也即上文代理模式中介紹的RealSubject對象。 在invoke()方法中,我們會打印它的所有參數,并調用當前代理的方法。 測試類
DynamicProxyDemo.java package com.zj.proxy.client; import java.lang.reflect.Proxy; import com.zj.proxy.Subject; import com.zj.proxy.RealSubject; import com.zj.proxy.dynamic.DynamicProxyHandler; public class DynamicProxyDemo { ??? public static void consumer(Subject subject) { ?????? subject.operation1(); ?????? subject.operation2("ZJ" ); ??? } ??? ??? public static void main(String[] args) { ??? ??? RealSubject real = new RealSubject(); ?????? System.out .println( "===Without Proxy===" ); ?????? consumer(real); ?????? System.out .println( "===Use Proxy===" ); ?????? Subject proxy = (Subject) Proxy.newProxyInstance(Subject.class ????????????? .getClassLoader(), new Class[] { Subject. class }, ????????????? new DynamicProxyHandler(real)); ?????? consumer(proxy); ??? } }
這里通過Proxy的靜態方法
newProxyInstance(ClassLoader loader, Class<?>[] interfaces,InvocationHandler h) 生成代理類,并傳遞與其關聯的調用處理程序
new DynamicProxyHandler(real) 。 對于newProxyInstance()的參數: [1]loader - 定義代理類的類加載器 ; [2]interfaces - 代理類要實現的接口列表 ; [3]h - 指派方法調用的調用處理程序 。 測試結果:
===Without Proxy=== Realer do operation1 Realer do operation2 with ZJ ===Use Proxy=== **** proxy: **** class $Proxy0 method: public abstract void com.zj.proxy.Subject.operation1() args: null Realer do operation1 **** proxy: **** class $Proxy0 method: public abstract void com.zj.proxy.Subject.operation2(java.lang.String) args: [Ljava.lang.Object;@de6f34 ? ZJ
Realer do operation2 with ZJ 從結果可以發現,通過代理可以得到當前被調用的方法,及其參數。代理過程可以基于此進行邏輯處理,測試程序只是簡單的打印這些相關信息。
本文出自 “子 孑” 博客,請務必保留此出處http://zhangjunhd.blog.51cto.com/113473/69996
總結
以上是生活随笔 為你收集整理的如何使用Proxy模式及Java内建的动态代理机制 的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔 網站內容還不錯,歡迎將生活随笔 推薦給好友。