Java面试_代理模式

在我们开始研究代理模式时,我们首先要知道代理模式是什么,之后再对正向代理,反向代理,静态代理和动态代理,下面我们从代理模式开始逐步介绍。

代理模式:

代理(Proxy)是GOF23中设计模式中的一种。提供了对目标对象另外的访问方式,即通过代理对象来访问目标对象。通俗来讲,代理对象就是我们平常生活中的中介,这样做的好处是:可以在目标对象实现的基础上,增强额外的功能操作,即扩展目标对象的功能。
举个比较容易懂的例子,网上购物大家都有过把,有时候我们如果想买国外商品,我们虽然可以自己去国外买,但是首先我们得先办理护照,然后买一张机票飞到国外去,然后找到有销售我们需要商品的超市,然后再过去购买到我们所需要的商品。这样虽然买到了我们需要的商品,但是却大大浪费了我们的时间和精力。我们的目的只是买商品为什么我们还做了那么多其他的事情呢。那么这时候,有没有一些专门在国外帮人买东西的人或机构呢,答案肯定是有的,我们就找了一个代购,也称之为中介,让他来帮我们代购商品,这样我们就可以省去中间的一系列繁琐的步骤,全权交给中介帮我们处理,我们只在最后收商品就可以了。用图片表示如下图:
在这里插入图片描述
正向代理:
正向代理是一个位于客户端和目标服务器之间的代理服务器,为了从目标服务器取得内容,客户端像代理服务器发送一个请求并指定目标,然后代理服务器向目标服务器转交请求并将获得的内容返回给客户端。客户端必须进行一些特别的配置才能使用正向代理,一般情况下,如果没有特别说明,代理技术默认是指正向代理。
这种代理其实在比较常见的,例如我们在我们中国大陆是没有办法访问外国的网站的,但是我们就可以通过代理服务器,让这个代理服务器接受我们的请求并帮我们去访问到外国网站并把响应返回给我们,这样我们就成功访问到外国网站了。这个过程就是用到了正向代理。过程如下图所示:
在这里插入图片描述
在通过正向代理服务器的时候,目标服务器是不知道真正的客户端是谁的,只知道是代理服务器在发送请求。

正向代理的用途:

  1. 突破访问限制:通过代理服务器,我们就可以突破自身的IP访问限制,我们就可以访问国外的网站等等。VPN技术就是通过正向代理,上面所说的例子也是通过VPN去访问的。
  2. 提高访问速度:通常代理服务器都设置一个较大的硬盘缓冲区。会将部分请求的响应保存再缓冲区中,当其它用户再访问相同信息的时候,则直接从缓冲区取出信息传给用户,以提高访问速度。
  3. 隐藏客户端真实IP:上网者也可以通过这种方式隐藏自己的IP,避免受到攻击。

既然有正向代理,那么自然有反向代理,接下来我们来看一下反向代理。

反向代理
反向代理是指代理服务器来接受internet上的连接请求,然后将请求转发给内部网络上的服务器,并将这些服务器上得到的结果返回给internet上请求连接的客户端,此时代理服务器对外就表现为一个反向代理服务器。这个怎么理解呢?我的理解就是,例如我通过中介去买东西,如果是正向代理的话,是我把我的需求告诉中介,然后中介根据我的需要去帮我购买。而反响代理就是卖家把它手上有的东西都交给中介,然后我找中介的时候,他就根据他手上有的东西来看有没有我需要的,有就给我,这样的话从我这边看我觉得中介就是一个卖家。反向代理如下图所示:
在这里插入图片描述

正向服务器和反向服务器的区别:
前面我们说过,通过正向代理服务器访问目标服务器,目标服务器是不知道真正的客户端是谁的,甚至不知道访问自己的是一个代理。而通过反向代理服务器访问目标服务器时,客户端是不知道真正的目标服务器是谁的,甚至不知道自己访问的是一个代理。这也是正向代理和反向代理的区别。

反向代理的用途:

  1. 隐藏服务器真实的IP:使用反响代理,可以对客户端隐藏服务器的IP地址
  2. 负载均衡:反向代理服务器可以做到负载均衡,根据所有真实服务器的负载情况,将客户端请求分发到不同的真实服务器上
  3. 提高访问速度:反向代理服务器可以对于静态内容及短时间内有大量访问请求的动态内容提供缓存服务,提高访问速度
  4. 提供安全保障:反向代理服务器可以作为应用层防火墙,为网站提供对基于Web的攻击行为(例如DoS/DDoS)的防护,更容易排查恶意软件等。还可以为后端服务器统一提供加密和SSL加速(如SSL终端代理),提供HTTP访问认证等。

上面说过了正向代理和反向道理,那现在我们来说一下静态代理和动态代理

静态代理
前面我们介绍的是计算机网络层的代理机制,一般指的是服务请求的处理。在java的日常开发中还会接触到另外一种代理,或者说是另外一种代理模式。在某些情况下,一个类不想或者不能直接引用一个对象,此时可以通过一个称之为“代理“的第三者来实现简介引用,代理对象可以在客户端和目标对象之间起到中介的作用,并且可以通过代理对象去掉客户不能看到的内容和服务或者添加客户需要的额外服务。
通过引入一个新的对象来实现对真实对象的操作或者将新的对象作为真实对象的一个替身,这种实现机制即为代理模式,通过引入代理对象来间接访问一个对象,这就是代理模式的模式动机。
代理代码如下图:(由于电脑没有编译环境,所以这是网上别人的)
在这里插入图片描述
在这里插入图片描述
上面就是一个简单的静态代理实现代码,由上面我们可以知道,静态代理中所有角色第一是在编译期就确定好的。那么这样也引出了一个问题,如果上面这个代码中要再加上一个别的代理对象,那么我们要怎么做呢,是不是得增加一个接口,在增加一个实现类,然后再在代理类中去实现,最后我们才能使用这个代理类代理另外的对象。你觉得这样好吗?
很显然这样是很不好的,当你做项目的时候,如果要扩展的话,必须去改以前的源代码,这样第一效率太低,第二鬼知道你在该源代码的时候还牵连到多少其他的文件,这时候就头皮发麻了。这样并不符合我们的开闭原则。(开闭原则规定“软件中的对象(类,模块,函数等等)应该对于扩展是开放的,但是对于修改是封闭的”,这意味着一个实体是允许在不改变它的源代码的前提下变更它的行为。),所以我们可以使用动态代理来解决这个问题。

动态代理
前面介绍了静态代理,虽然静态代理模式很好用,但是静态代理还是存在一些局限性的,比如使用静态代理模式需要程序员手写很多代码,这个过程是比较浪费时间和精力的。一旦需要代理的类中方法比较多,或者需要同时代理多个对象的时候,这无疑会增加很大的复杂度。
有没有一种方法,可以不需要程序员自己手写代理类呢。这就是动态代理。
上面说到静态代理是在编译期就确定好的,而动态代理中的代理类并不要求编译期就确定,而是可以在运行期动态生成,从而实现对目标对象的代理功能。

在Java中,实现动态代理有两种方式:

  1. JDK动态代理:JDK动态代理是Java.lang.reflect包中的Proxy类和InvocationHandler接口提供了生成动态代理类的能力。
  2. Gglib动态代理:Cglib(Code Generation Library)是一个第三方代码生成的类库,运行时在内存中动态生成一个子类对象从而实现对目标对象功能的扩展。

如果想看JDK动态代理和Cglib动态代理。那么戳我
代理模式和spring aop中源码实现。那么戳我

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值