如何使用Proxy模式及Java内建的动态代理机制

1.Proxy模式
代理模式支持将某些操作从实际的对象中分离出来,通过它的代理类提供处理。这样便于修改和管理这些特定的操作。
下面示例一个代理模式的实现。

<<interface>>Subject.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.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  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
<td 230,="" 230)="" none="" repeat="" scroll="" 0%="" 50%;="" width:="" 426.1pt;="" -moz-background-clip:="" -moz-initial;="" -moz-background-origin:="" -moz-background-inline-policy:="" -moz-initial;"="" valign="top" width="568" style="padding-top: 0cm; padding-right: 5.4pt; padding-bottom: 0cm; padding-left: 5.4pt; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; background-image: initial; background-attachment: initial; background-origin: initial; background-clip: initial; background-color: white; border-top-width: 1pt; border-right-width: 1pt; border-bottom-width: 1pt; border-left-width: 1pt; border-top-style: solid; border-right-style: solid; border-bottom-style: solid; border-left-style: solid; border-top-color: windowtext; border-right-color: windowtext; border-bottom-color: windowtext; border-left-color: windowtext; border-image: initial; ">
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
从结果可以发现,通过代理可以得到当前被调用的方法,及其参数。代理过程可以基于此进行逻辑处理,测试程序只是简单的打印这些相关信息。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值