前言:设计模式继续,今天学习代理模式。
代理模式(Proxy)
代理要做的就是:控制和管理访问。代理其实就是真实对象的代表。
定义:为其他对象提供一种代理以控制对这个对象的访问。
目的:能达到的目的是为一个对象扩展功能。
结构图:
一、如何理解控制访问?
比如远程代理控制访问,其实就是控制网络上的细节。控制访问远程对象。
比如虚拟代理控制访问创建开销大的资源。
比如保护代理基于权限控制对资源的访问。
二、java 代理模式分类:
静态代理:在编译期就已经存在代理类。缺点是:目标类接口变更,需要修改代理类。
jdk 动态代理:运行时动态生成代理类,使用反射进行方法的调用。缺点是:只能够代理实现了接口(InvocationHandler)的目标类。深入理解JDK动态代理机制。
cglib 动态代理:使用字节码动态生成代理类,底层将方法全部存入一个数组中,通过数组索引直接进行方法调用。缺点是:不能对final类以及final方法进行代理
找到一篇例子:Java的三种代理模式简述
在 Spring 的 AOP 实现中,主要应用了 JDK 动态代理以及 CGLIB 动态代理。如果代理对象实现了接口,则默认使用jdk动态代理,也可强制使用cglib代理,如果未实现接口则只能使用cglib代理。
动态代理,我们不知道要针对哪个接口、哪个被代理类创建代理类,因为它是在运行时被创建的。
三、应用场景:
1、远程代理,也就是为一个对象在不同的地址空间提供局部代表。这样可以隐藏一个对象存在于不同地址空间的事实。(下面有讲解)
2、虚拟代理,是根据需要创建开销很大的对象。通过它来存放实例化需要很长时间的真实对象。来达到性能的最优化。
比如:打开一个很大的 HTML 网页时,里面可能有很多的文字和图片,但我们还是可以很快打开它,此时我们所看到的是所有的文字,但图片却是一张一张地下载后才能看到。那些未打开的图片框,就是通过虚拟代理来替代了真实的图片,此时代理存储了真实的路径和尺寸。所以浏览器当中是通过代理模式来优化下载的。
3、安全代理(保护代理),用来控制真实对象访问的权限。
4、智能指引,是指当调用真实的对象时,代理处理另外一些事。
比如:计算真实对象的引用次数,这样当该对象没有引用时,可以自动释放它;或当第一次引用一个持久对象时,将它装入内存;或在访问一个实际对象前,检查是否已经锁定它,以确保其他对象不能改变它。它们都是通过代理在访问一个对象时附加一些内务处理。
1、远程代理
我理解的就是,自己的服务器需要访问(使用代理访问)另一个服务器上的对象。也就是在自己的 JVM 环境里调用代理对象的方法,由代理对象去通过网络或者 I/O 来访问真实的对象,这里的代理对象存在于自己的 JVM 环境里。
简单来说,当你想在自己的 JVM 环境里访问一个对象的方法,但是这个对象在另一个 JVM 堆里,如果要访问,则需要通过网络来实现。这时使用远程代理,在自己的 JVM 里新建一个代理对象,我调用的就是这个代理对象的方法,我并不需要知道这时是由代理对象来负责通过网络来访问真实的那个对象。
代理对象如何调用远程的对象?有一种方法是使用 RMI,这里简单讲一下 RMI。
java 的 RMI 可以做到。不过现在用的很少了吧。
RMI 提供了客户辅助对象(代理对象)、服务辅助对象。
RMI 的好处在于不必亲自写人和的网络或 I/O 代码。
如何将对象变为服务,使之可以接受远程的调用?使用 RMI 的一些东西,需要了解 RMI 的知识。
RMI 过程:由客户调用客户辅助对象 -> 客户辅助对象通过网络调用服务辅助对象 -> 服务辅助对象调用真实的服务对象
四、扩展一下反向代理、正向代理
在公司,经常听到反向代理,正向代理,所以这两个又是啥?
反向代理,正向代理其实都是代理模式。
正向代理:是一个位于客户端和原始服务器(origin server)之间的服务器,为了从原始服务器取得内容,客户端向代理发送一个请求并指定目标(原始服务器),然后代理向原始服务器转交请求并将获得的内容返回给客户端。客户端才能使用正向代理。
反向代理(Reverse Proxy):方式是指以代理服务器来接受 internet 上的连接请求,然后将请求转发给内部网络上的服务器,并将从服务器上得到的结果返回给 internet 上请求连接的客户端,此时代理服务器对外就表现为一个反向代理服务器。
正向代理和反向代理不同之处在于,典型的正向代理是一种最终用户知道并主动使用的代理方式。例如Chrome浏览器中安装了switchysharp以后,通过switchysharp方便地进行代理转发服务。而为此用户必须要提前在switchysharp中做好设置才能达到相应的效果。
这里附上我在网上看到的一篇容易理解的文章:正向代理与反向代理【总结】