代理模式是二十多种设计模式中的一个,属于比较常用的设计模式。本质上就是用来委托我们生成的代理类去完成一些额外的功能,这样能够达到解耦、封装的目的。
通常可以用在RPC、AOP中。比如在RPC中,当我们调用远程方法时,需要委托代理类帮助我们去通过网络连接远程的服务提供者,帮助我们将消息编码发送给服务端,帮我们接受服务端发来的结果。

静态代理

在代理模式中,通常指的时静态代理。

这是静态代理的UML图。代理的思想是:代理类ProxySubject拥有实际类RealSubject的相同方法doSomething(实现相同的一个接口),同时代理类内聚了实际类(即传入实际类的一个引用),在代理类的doSomething方法中,通过实际类的引用调用实际类的doSomething方法,并在调用前后加入需要代理实现的额外功能。这样我们就可以通过调用代理类的相同方法来达到我们的目的。
举个例子:

    interface Subject{void doSomething();}
class RealSubject implements Subject{void doSomething(){System.out.println("doSomething");}
}
class ProxySubject implements Subject{private Subject target;public ProxySubject(Subject target){this.target = target;}void doSomething(){//do beforeSystem.out.println("do before");target.doSomething();//调用realSubject的doSomething方法//do afterSystem.out.println("do after");}
}
class ProxyTest{public static void main(String args[]){//生成代理类,并将实际类传入ProxySubject proxy = new ProxySubject(new RealSubject());proxy.doSomething();}
}

以上,通过代理类执行实际类相同的方法,我们可以运行额外的功能。这里不仅会运行实际类doSomething方法里面的打印“doSomething”,还会在之前打印“do before",之后打印”do after",这两个即为额外的功能。

动态代理

上面的静态代理其实存在一个问题,一个实际类对应一个代理类,而很多时候需要代理实现的额外功能是相同的,比如我们要在A类的某个方法调用前打印“before”,B类的某个方法调用前打印“before”,C类也有这个需求,如果用静态代理,我们需要写A类的代理,B类的代理,C类的代理。。。这样岂不是要累死。
java当中的动态代理就是为了这个解决这个问题。其实思路也很简单,不用去管A类、B类、C类还是什么其他类,统一用反射调用实际类的方法。
java提供了动态代理类Proxy,使用其中的静态方法Proxy.newProxyInstance(ClassLoader loader,Class<?>[] interfaces, InvocationHandler h)来动态生成代理类。interfaces为实际类的接口,对应上面图中的Subject,loader为接口的Classloader,InvocationHandler接口有一个invoke方法需要自己实现,我们委托代理类实现的额外功能便放在该方法里。需要注意的是由此看出java的动态代理需要有接口才能使用。如果不用接口实现动态代理只能求助于cglib这类字节码增强框架。
下面是动态代理的一般实现方法:

public class InvokeProxy implements InvocationHandler{private Object target;public Object bind(Object target){this.target = target;return Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), this);}@Overridepublic Object invoke(Object proxy, Method method, Object[] args)throws Throwable {System.out.println("do something before");method.invoke(target, args);System.out.println("do something after");return null;/*如果反射调用的方法有返回值:Object result;result = method.invoke(target, args);return result;*/}}

同样有接口Subject:

 interface Subject{void doSomething();}

假设类A实现了Subject接口,可以根据如下代码生成A的代理

public class ProxyTest {public static void main(String[] args) {Subject proxyA = (Subject)new InvokeProxy().bind(new A());proxyA.doSomething();}}

如果还有类B实现了Subject接口,我们只需更改上面的代码即可,而不用像静态代理那样重复的编写代码。这就是动态代理相对于静态代理的意义。

代理模式、动态代理及其应用相关推荐

  1. 【设计模式】代理模式 ( 动态代理 | 模拟 Java 虚拟机生成对应的 代理对象 类 )

    文章目录 前言 一.模拟 JVM 生成对应的 代理对象 二.模拟 JVM 生成对应的 代理对象 完整流程展示 1.目标对象接口 2.被代理对象 3.调用处理程序 4.模拟 JVM 生成的代理对象类 5 ...

  2. 红橙Darren视频笔记 代理模式 动态代理和静态代理

    红橙Darren视频笔记 代理模式 动态代理和静态代理(Android API 25) 关于代理模式我之前有过相关的介绍: https://blog.csdn.net/u011109881/artic ...

  3. 【设计模式】代理模式 ( 动态代理使用流程 | 创建目标对象 | 创建被代理对象 | 创建调用处理程序 | 动态创建代理对象 | 动态代理调用 )

    文章目录 前言 一.静态代理的弊端 二.动态代理的优势 三.动态代理使用流程 1.目标对象接口 2.被代理对象 3.调用处理程序 4.客户端 四.动态生成 代理对象 类 的 字节码 文件数据 前言 代 ...

  4. Proxy 代理模式 动态代理 CGLIB

    代理的基本概念 几个英文单词: proxy [ˈprɒksi] n. 代理服务器:代表权:代理人,代替物:委托书: invoke [ɪnˈvəʊk] vt. 乞灵,祈求:提出或授引-以支持或证明:召鬼 ...

  5. Java设计模式-之代理模式(动态代理)

    一.简介 1.什么叫代理模式:        简而言之就是:为其他对象提供一种代理以控制对这个对象的访问.在某些情况下,一个对象不适合或者不能直接引用另一个对象,而代理对象可以在客户端和目标对象之间起 ...

  6. 【设计模式】代理模式 ( 动态代理 )

    文章目录 一.动态代理使用流程 二.动态代理代码示例 1.订单类 2.Service 接口 3.Service 实现类 4.Service 静态代理类 5.Dao 接口 6.Dao 实现类 7.Ser ...

  7. 代理模式(动态代理)

    动态代理.就是不用自己写代理类,只要实现接口就行了. 动态代理,这里介绍两种:jdk and cglib 第一个jdk //一个接口类 public interface Book{void read( ...

  8. Spring AOP中的静态代理和动态代理的原理和实践

    对于最近博主最近写博客的兴致大发,我也在思考:为什么而写博客?在互联网时代,无论你是牛人大咖,还是小白菜鸟,都有发表自己看法的权利.无论你是对的还是错的,都会在这个平台上找到答案.所以,我会尽可能去写 ...

  9. 【java项目实战】代理模式(Proxy Pattern),静态代理 VS 动态代理

    这篇博文,我们主要以类图和代码的形式来对照学习一下静态代理和动态代理.重点解析各自的优缺点. 定义 代理模式(Proxy Pattern)是对象的结构型模式,代理模式给某一个对象提供了一个代理对象,并 ...

  10. 【Android 插件化】Hook 插件化框架 ( Hook 技术 | 代理模式 | 静态代理 | 动态代理 )

    Android 插件化系列文章目录 [Android 插件化]插件化简介 ( 组件化与插件化 ) [Android 插件化]插件化原理 ( JVM 内存数据 | 类加载流程 ) [Android 插件 ...

最新文章

  1. 以太坊智能合约开发:让合约接受转账
  2. 随机过程在数据科学和深度学习中有哪些应用?
  3. unity3D常见问题
  4. Bootstrap鼠标悬停下拉导航总结
  5. MySQL5.6 部署MHA
  6. php header函数的详解,php header函数的详解_PHP教程
  7. cad图纸怎么看懂_CAD图纸太大,打开的时候很卡怎么办?教你如何给图纸瘦身
  8. 【基础】位与运算与取余
  9. 转 Git-fatal: unable to access 'xxx' : Could not resolve host: xxx
  10. 计算电磁学基础知识及数值方法汇总
  11. wav格式转换成mp3,wav转mp3教程
  12. 腾讯云IM-SDK集成(web端)完成IM登录
  13. 北斗导航 | GBAS发展与应用支持CAT II/III类精密进近
  14. html中鼠标悬停图片变大,JavaScript通过mouseover()实现图片变大效果的示例
  15. 基于linux的oracle_rac实时应用集群研究,基于Linux的OracleRAC实时应用集群研究毕业设计论文(资料4)...
  16. 打开单片机世界的大门——上位机控制下位机实例详解
  17. 通过Hook API调用打造进程监控程序
  18. HashMap扩容为什么是2的倍数
  19. 传奇服务器充值系统,传奇服务端会员系统COM引擎传奇增加会员系统的方法
  20. 以root身份登录ylmf4.0

热门文章

  1. 《网页设计与前端开发 Dreamweaver+Flash+Photoshop+HTML+CSS+JavaScript 从入门到精通》—— 第1章 网页设计基础知识...
  2. 微软、谷歌、百度等公司经典面试100题[第1-60题]——自己的实现[转]
  3. 让局域网内部挺高网速
  4. Dynamo论文导读
  5. smart原则_《红楼梦》凤姐做领导为什么积劳成疾?只因为不懂SMART原则
  6. JS事件循环 Event Loop
  7. 如何用firebug调试js
  8. android bu,Android请求权限之不再询问或禁止不再提示
  9. 在Sping Boot logback的使用
  10. 使用Docker安装Redis