生活随笔
收集整理的這篇文章主要介紹了
如何使用Proxy模式及Java内建的动态代理机制
小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
http://zhangjunhd.blog.51cto.com/113473/69996
1.Proxy模式 代理模式支持將某些操作從實(shí)際的對(duì)象中分離出來(lái),通過(guò)它的代理類提供處理。這樣便于修改和管理這些特定的操作。 下面示例一個(gè)代理模式的實(shí)現(xiàn)。 <!--[if !vml]-->
<!--[endif]--> <<interface>>Subject.java
package com.zj.proxy; public interface Subject { ??? void operation1(); ??? ??? void operation2(String arg); }
現(xiàn)實(shí)類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 ; // 被代理對(duì)象 ??? 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); ??? } }
測(cè)試類
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)); ??? } }
結(jié)果:
===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的動(dòng)態(tài)代理機(jī)制 設(shè)計(jì)一個(gè)類用于實(shí)現(xiàn)InvocationHandle接口,InvocationHandler 是代理實(shí)例的調(diào)用處理程序?qū)崿F(xiàn)的接口。 每個(gè)代理實(shí)例都具有一個(gè)關(guān)聯(lián)的調(diào)用處理程序。對(duì)代理實(shí)例調(diào)用方法時(shí),將對(duì)方法調(diào)用進(jìn)行編碼并將其指派到它的調(diào)用處理程序的 invoke 方法。 <<interface>>InvocationHandle.java
package java.lang.reflect; public interface InvocationHandler { ??? public Object invoke(Object proxy, Method method, Object[] args) ??? throws Throwable; }
對(duì)應(yīng)invoke參數(shù): [1]proxy - 在其上調(diào)用方法的代理實(shí)例; [2]method - 對(duì)應(yīng)于在代理實(shí)例上調(diào)用的接口方法的 Method 實(shí)例; [3]args - 包含傳入代理實(shí)例上方法調(diào)用的參數(shù)值的對(duì)象數(shù)組,如果接口方法不使用參數(shù),則為 null。 現(xiàn)在設(shè)計(jì)一個(gè)類實(shí)現(xiàn)該接口,并提供代理實(shí)例。
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 ; 即代理實(shí)例,也即上文代理模式中介紹的RealSubject對(duì)象。 在invoke()方法中,我們會(huì)打印它的所有參數(shù),并調(diào)用當(dāng)前代理的方法。 測(cè)試類
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); ??? } }
這里通過(guò)Proxy的靜態(tài)方法
newProxyInstance(ClassLoader loader, Class<?>[] interfaces,InvocationHandler h) 生成代理類,并傳遞與其關(guān)聯(lián)的調(diào)用處理程序
new DynamicProxyHandler(real) 。 對(duì)于newProxyInstance()的參數(shù): [1]loader - 定義代理類的類加載器 ; [2]interfaces - 代理類要實(shí)現(xiàn)的接口列表 ; [3]h - 指派方法調(diào)用的調(diào)用處理程序 。 測(cè)試結(jié)果:
===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 從結(jié)果可以發(fā)現(xiàn),通過(guò)代理可以得到當(dāng)前被調(diào)用的方法,及其參數(shù)。代理過(guò)程可以基于此進(jìn)行邏輯處理,測(cè)試程序只是簡(jiǎn)單的打印這些相關(guān)信息。
本文出自 “子 孑” 博客,請(qǐng)務(wù)必保留此出處http://zhangjunhd.blog.51cto.com/113473/69996
總結(jié)
以上是生活随笔 為你收集整理的如何使用Proxy模式及Java内建的动态代理机制 的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
如果覺(jué)得生活随笔 網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔 推薦給好友。