博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Java动态代理
阅读量:5312 次
发布时间:2019-06-14

本文共 5032 字,大约阅读时间需要 16 分钟。

  在学习《Java编程思想》的时候看到了动态代理,觉得很有意思,现在来做一下总结。

一、代理模式的定义

  为其他对象提供一种以控制对这个对象的访问。在某些情况下,一个对象不适合或者不能直接引用另一个对象,而代理对象可以在和目标对象之间起到中介的作用。

二、优点

  (1).职责清晰真实的角色就是实现实际的,不用关心其他非本职责的事务,通过后期的代理完成一件完成事务,附带的结果就是编程简洁清晰。
  (2).代理对象可以在和目标对象之间起到中介的作用,这样起到了的作用和保护了目标对象的作用。
  (3).高扩展性

三、模式结构

  一个是真正的你要访问的对象(目标类),一个是代理对象,真正对象与代理对象实现同一个接口,先访问代理类再访问真正要访问的对象。

四、UML示意图

 

  我们来看一个普通代理实现的例子:

1 //客户端接口 2 interface Interface { 3  4     void doSomething(); 5  6     void somethingElse(String arg); 7 } 8  9 //客户端实现类,就是执行业务逻辑的类10 class RealObject implements Interface {11 12     @Override13     public void doSomething() {14         // TODO Auto-generated method stub15         System.out.println("doSomething");16     }17 18     @Override19     public void somethingElse(String arg) {20         // TODO Auto-generated method stub21         System.out.println("somethingElse" + arg);22     }23 24 }25 26 //代理类27 class SimpleProxy implements Interface {28 29     private Interface proxied;30 31     public SimpleProxy(Interface proxied) {32         // TODO Auto-generated constructor stub33         this.proxied = proxied;34     }35 36     @Override37     public void doSomething() {38         // TODO Auto-generated method stub39         System.out.println("SimpleProxy doSomething");40         proxied.doSomething();41     }42 43     @Override44     public void somethingElse(String arg) {45         // TODO Auto-generated method stub46         System.out.println("SimpleProxy somethingElse "+arg);47         proxied.somethingElse(arg);48     }49 50 }51 52 public  class SimpleProxyDemo{53     54     public static void consumer(Interface iface){55         iface.doSomething();56         iface.somethingElse("hello world");57     }58     59     public static void main(String[] args){60         consumer(new RealObject());61         System.out.println("/*****************************/");62         consumer(new SimpleProxy(new RealObject()));63     }64 }

 运行结果如下:

1 doSomething2 somethingElsehello world3 /*****************************/4 SimpleProxy doSomething5 doSomething6 SimpleProxy somethingElse hello world7 somethingElsehello world

五、Java动态代理

  Java的动态代理比代理的思想更向前迈进了一步,因为它可以动态地创建代理并动态地处理对所代理方法的调用。在动态代理上所做的所有调用都会被重定向到单一的调用处理器上,它的工作揭示调用的类型并确定相应的对策。 

接下来我们来看一下Java动态代理的例子:

1  interface Interface { 2  3     void doSomething(); 4  5     void somethingElse(String arg); 6 } 7  8 class RealObject implements Interface { 9 10     @Override11     public void doSomething() {12         // TODO Auto-generated method stub13         System.out.println("doSomething");14     }15 16     @Override17     public void somethingElse(String arg) {18         // TODO Auto-generated method stub19         System.out.println("somethingElse" + arg);20     }21 22 }23 24 //动态代理类25 class DynamicProxyHandler implements InvocationHandler{26 27     private Object proxied;28     29     public DynamicProxyHandler(Object proxied) {30         // TODO Auto-generated constructor stub31         this.proxied = proxied;32     }33 34     @Override35     public Object invoke(Object proxy, Method method, Object[] args)36             throws Throwable {37         // TODO Auto-generated method stub38         System.out.println("****proxy: " + proxy.getClass()+39                 ", method: "+method+ ", args: "+ args);40         41         if(args != null){42             for (Object arg : args) {43                 System.out.println("  "+ arg);44             }45         }46         47         return method.invoke(proxied, args);48     }49 }50 51 class SimpleDynamicProxy{52     53     public static void consumer(Interface iface){54         iface.doSomething();55         iface.somethingElse("hello world");56     }57     58     public static void main(String[] args){59         RealObject real = new RealObject();60         consumer(real);61         62         System.out.println("/*******************************/");63         64         Interface proxy = (Interface)Proxy.newProxyInstance(65                 Interface.class.getClassLoader(), 66                 new Class[]{Interface.class},67                 new DynamicProxyHandler(real));68         69         consumer(proxy);70         71     }72     73 }

运行结果如下:

1 doSomething2 somethingElsehello world3 /*******************************/4 ****proxy: class com.sun.proxy.$Proxy0, method: public abstract void Interface.doSomething(), args: null5 doSomething6 ****proxy: class com.sun.proxy.$Proxy0, method: public abstract void Interface.somethingElse(java.lang.String), args: [Ljava.lang.Object;@756095fc7   hello world8 somethingElsehello world

   通过调用静态方法Proxy.newProxyInstance()可以创建动态代理。这个方法需要得到一个类加载器(你通常可以从已经被加载的对象中获取其类加载器,然后传递给它),一个你希望该代理实现的接口列表(不是类或者抽象类),以及InvocationHandler接口的一个实现。动态代理可以将所有调用重定向到调用处理器,因此通常会向调用处理器的构造器传递一个“实际”对象的引用,从而使得调用处理器执行其中介任务时,可以将请求转发。

   invoke()方法传递进来了代理对象,以防你需要区分请求的来源,但是在许多情况下,你并不关心这一点。然而,在invoke()内部,在代理上调用方法时需要格外小心,因为接口的调用将被重定向为对代理对象的调用。

  通常,你会执行被代理的操作,然后使用Method.invoke()将请求转发给 被代理对象,并传入必需的参数。这初看起来可能有些受限,就像你只能执行泛化操作一样。但是,你可以通过传递其他的参数,来过滤某些方法的调用。

转载于:https://www.cnblogs.com/yfyzy/p/4401833.html

你可能感兴趣的文章
bzoj2257
查看>>
http://www.bootcss.com/
查看>>
20145308 《网络对抗》 注入shellcode+Return-to-libc攻击 学习总结
查看>>
将多张图片和文字合成一张图片
查看>>
自己动手写ORM(01):解析表达式树生成Sql碎片
查看>>
如何使用USBWebserver在本机快速建立网站测试环境
查看>>
变量提升
查看>>
[Flex] flex手机项目如何限制横竖屏?只允许横屏?
查看>>
tensorflow的graph和session
查看>>
JavaScript动画打开半透明提示层
查看>>
Mybatis生成resulteMap时的注意事项
查看>>
jquery-jqzoom 插件 用例
查看>>
1007. Maximum Subsequence Sum (25)
查看>>
图片生成缩略图
查看>>
查看oracle数据库的连接数以及用户
查看>>
【数据结构】栈结构操作示例
查看>>
三.野指针和free
查看>>
activemq5.14+zookeeper3.4.9实现高可用
查看>>
TCP/IP详解学习笔记(3)IP协议ARP协议和RARP协议
查看>>
简单【用户输入验证】
查看>>