java中的代理是什么意思?

Python013

java中的代理是什么意思?,第1张

代理模式在设计模式中的定义就是:为其他对象提供一种代理以控制对这个对象的访问。说白了就是,在一些情况下客户不想或者不能直接引用一个对象,而代理对象可以在客户和目标对象之间起到中介作用,去掉客户不能看到的内容和服务或者增添客户需要的额外服务。

从JDK1.5开始,Java在java.net包下提供了Proxy和ProxySelector两个类,其中Proxy代表一个代理服务器,可以在打开URLConnection连接时指定所用的Proxy实例,也可以在创建Socket连接时指定Proxy实例。而ProxySelector代表一个代理选择器,它提供了对代理服务器更加灵活的控制,它可以对HTTP、HTTPS、FTP、SOCKS等分别设置,而且还可以设置不需要通过代理服务器的主机和地址。通过使用ProxySelector可以达到像在Internet Explorer、FireFox等软件中设置代理服务器类似的效果。

代理服务器的功能就是代理网络用户去取得网络信息。我们使用网络浏览器直接连接其他Internet站点取得网络信息时,通常需要发送Request请求来等到响应。代理服务器是介于浏览器和Web服务器之间的一台服务器,有了它之后,浏览器不是直接到Web服务器去取得网页数据而是向代理服务器发出请求,Request请求会先送到代理服务器,由代理服务器来取回浏览器所需要的信息并送回给网络浏览器。而且,大部分代理服务器都具有缓冲的功能,就好像一个大的Cache,它有很大的存储空间,它不断将新取得的数据储存到它本机的存储器上,如果浏览器所请求的数据在它本机的存储器上已经存在而且是最新的,那么它就不重新从Web服务器取数据,而直接将存储器上的数据传送给用户的浏览器,这样就能显著提高浏览速度和效率。归纳起来代理服务器主要提供如下两个功能:

突破自身IP限制,对外隐藏自身IP地址。突破IP限制包括访问国外受限站点,访问国内特定单位、团体的内部资源。

提高访问速度,代理服务器提供的缓冲功能可以避免每个用户都直接访问远程主机,从而提高客户端访问速度。

17.5.1 直接使用Proxy创建连接

Proxy有如下一个构造器:Proxy(Proxy.Type type, SocketAddress sa):创建表示代理服务器的Proxy对象。而sa参数指定代理服务器的地址,其中type是该代理服务器的类型,该服务器类型有如下三种:

(1)Proxy.Type.DIRECT:表示直接连接或缺少代理。

(2)Proxy.Type.HTTP:表示高级协议的代理,如 HTTP 或 FTP。

(3)Proxy.Type.SOCKS:表示 SOCKS(V4 或 V5)代理。

一旦创建了Proxy对象之后,程序就可以在使用URLConnection打开连接时,或创建Socket连接时传入一个Proxy对象,作为本次连接所使用的代理服务器。

其中URL包含了一个URLConnection openConnection(Proxy proxy)方法,该方法使用指定的代理服务器来打开连接;而Socket则提供了一个Socket(Proxy proxy)构造器,该构造器使用指定的代理服务器创建一个没有连接的Socket对象。

下面以URLConnection为例来介绍如何在URLConnection中使用代理服务器。

程序清单:codes/17/17-5/ProxyTest.java

上面代码第一行粗体字代码创建了一个Proxy对象,第二行粗体字代码就是用Proxy对象来打开URLConnection连接。除此之外,该程序的其他地方就是对URLConnection的使用了。由此可见, JDK1.5提供了对代理服务器很好的支持。

17.5.2 使用ProxySelector选择代理服务器

前面介绍的直接使用Proxy对象可以在打开URLConnection或Socket时指定代理服务器,使用这种方式需要每次打开连接都显式设置代理服务器。如果想让系统打开连接时总是具有默认的代理服务器,则可以使用java.net.ProxySelector,它可以它根据不同的连接使用不同的代理服务器。

系统默认的ProxySelector会检测各种系统属性和URL协议,然后决定怎样连接不同的主机。当然,程序也可以调用ProxySelector类的setDefaultI()静态方法来设置默认代理服务器,也可以调用getDefault()方法获得系统当前默认的代理服务器。

程序可以通过System类来设置系统的代理服务器属性,关于代理服务器常用的属性名有如下三个:

http.proxyHost:设置HTTP访问所使用的代理服务器地址。该属性名的前缀可以改为https、ftp等,分别用于设置HTTP访问、安全HTTP访问和FTP访问所用的代理服务器地址。

http.proxyPort:设置HTTP访问所使用的代理服务器端口。该属性名的前缀可以改为https、ftp等,分别用于设置HTTP访问、安全HTTP访问和FTP访问所用的代理服务器端口。

http.nonProxyHosts:设置HTTP访问中不需要使用代理服务器的远程主机,可以使用*通配符,如果有多个地址,多个地址用竖线(|)分隔。

下面程序示范了通过改变系统属性来改变默认的代理服务器。

程序清单:codes/17/17-5/ ProxySelectorTest.java

上面程序中三行粗体字代码设置Java打开HTTP访问时的代理服务器属性,其中前两行代码设置代理服务器的地址和端口,第三行代码设置该代理HTTP访问哪些主机时不需要使用代理服务器。上面程序的①行代码处直接打开一个URLConnection,但系统会为打开该URLConnection时使用代理服务器。

运行上面程序,将会看到程序长时间等待,因为192.168.0.96通常并不是有效的代理服务器(当然,如果读者运行的机器恰好可以使用地址为192.168.0.96的代理服务器又另当别论)。

系统提供了默认的ProxySelector子类作为代理选择器,开发者可以实现自己的代理选择器,程序可以通过继承ProxySelector来实现自己的代理选择器。继承ProxySelector需要重写两个方法:

List<Proxy>select(URI uri):实现该方法让代理选择器根据不同的URI来使用不同的代理服务器,该方法就是代理选择器管理网络连接使用代理服务器的关键。

connectFailed(URI uri, SocketAddress sa, IOException ioe):当系统通过默认的代理服务器建立连接失败后,代理选择器将会自动调用该方法。通过重写该方法可以对连接代理服务器失败的情形进行处理。

系统默认的代理服务器选择器也重写了connectFailed方法,它重写该方法的处理策略是:当系统设置的代理服务器失败时,默认代理选择器将会采用直连的方式连接远程资源,所以当运行上面程序等待了足够长时间时,程序依然可以打印出该远程资源的所有内容。

Java动态代理机制的出现,使得Java开发人员不用手工编写代理类,只要简单地制定一组接口及委托类对象,便能动态地获得代理类。代理类会负责将所有的方法调用分配到委托对象上反射执行,配置执行过程中,开发人员还可以进行修改

代理设计模式

代理是一种常用的设计模式,其目的就是为其他对象提供一个代理以控制对某个对象的访问。代理类负责为委托类预处理消息、过滤消息并转发消息,以及进行消息被委托类执行后的后续处理。

为了保持行为的一致性,代理类和委托类通常会实现相同的接口

2. 引入代理能够控制对委托对象的直接访问,可以很好的隐藏和保护委托对象,也更加具有灵活性

代理机制及其特点

首先让我们来了解一下如何使用 Java 动态代理。具体有如下四步骤:

通过实现 InvocationHandler 接口创建自己的调用处理器;

通过为 Proxy 类指定 ClassLoader 对象和一组 interface 来创建动态代理类;

通过反射机制获得动态代理类的构造函数,其唯一参数类型是调用处理器接口类型;

通过构造函数创建动态代理类实例,构造时调用处理器对象作为参数被传入。

代理类实例的一些特点 

每个实例都会关联一个InvocationHandler(调用处理器对象),在代理类实例上调用其代理接口中声明的方法时,最终都会由InvocationHandler的invoke方法执行;

java.lang.Object中有三个方法也同样会被分派到调用处理器的 invoke 方法执行,它们是 hashCode,equals 和 toString;

代码示例

最后以一个简单的动态代理例子结束