1.Spring中,HTTPInvoker(HTTP调用器)是通过基于HTTP协议的分布式远程调用解决方案,和java RMI一样,HTTP调用器也需要使用java的对象序列化机制完成客户端和服务器端的通信。HTTP调用器的远程调用工作原理如下:
(1).客户端:
a.向服务器发送远程调用请求:
远程调用信息——>封装为远程调用对象——>序列化写入到远程调用HTTP请求中——>向服务器端发送。
b.接收服务器端返回的远程调用结果:
服务器端返回的远程调用结果HTTP响应——>反序列化为远程调用结果对象。
(2).服务器端:
a.接收客户端发送的远程调用请求:
客户端发送的远程调用HTTP请求——>反序列化为远程调用对象——>调用服务器端目标对象的目标方法处理。
b.向客户端返回远程调用结果:
服务器端目标对象方法的处理结果——>序列化写入远程调用结果HTTP响应中——>返回给客户端。
接下来我们将从客户端和服务器端分别分析HTTP调用器远程调用的具体实现。
2.HTTP调用器客户端配置:
使用HTTP调用器之前,首先需要对客户端其进行如下的配置:
[xhtml] view plaincopyprint
-
-
http://yourhost:8080/远程调用URL -
-
远程调用服务接口全路径 -
-
-
在HTTP调用器客户端代理HttpInvokerProxyFactoryBean中封装远程调用服务URL和服务接口,客户端程序通过HTTP调用代理可以调用实现了指定接口的目标服务端对象。
3.HttpInvokerProxyFactoryBean创建远程调用代理对象:
HTTP调用器客户端代理HttpInvokerProxyFactoryBean是一个实现了Spring FactoryBean接口的IoC容器,其作用是对远程服务客户端封装,源码如下:
[java] view plaincopyprint- public class HttpInvokerProxyFactoryBean extends HttpInvokerClientInterceptor implements FactoryBean
- private Object serviceProxy; //在IoC容器注入完成之后调用
- public void afterPropertiesSet() { //调用父类容器的回调方法
- super.afterPropertiesSet(); //getServiceInterface()方法用于获取配置的远程调用接口
- if (getServiceInterface() == null) { throw new IllegalArgumentException("Property 'serviceInterface' is required");
- } //使用ProxyFactory代理工厂生成远程代理对象,注意第二个参数this,因为
- //HttpInvokerProxyFactoryBean继承了HttpInvokerClientInterceptor, //所以代理对象的拦截器设置为HttpInvokerClientInterceptor
- this.serviceProxy = new ProxyFactory(getServiceInterface(), this).getProxy(getBeanClassLoader()); }
- //向IoC容器索取被管理对象的方法,获取产生的远程调用代理对象 public Object getObject() {
- return this.serviceProxy; }
- //获取对象类型,返回配置的远程调用接口 public Class getObjectType() {
- return getServiceInterface(); }
- //是否是单态类型,默认Spring IoC容器产生的都是单态类型 public boolean isSingleton() {
- return true; }
- }
通过上面对HttpInvokerProxyFactoryBean源码的分析我们看到,当通过getObject方法向Spring IoC容器索取远程调用对象时,触发afterPropertiesSet回调方法,创建远程调用的代理对象,最后将该远程调用代理对象返回。在创建远程调用代理对象时,使用其父类HttpInvokerClientInterceptor作为远程调用代理对象的拦截器,该拦截器将拦截对代理对象的方法调用。下面我们分析HttpInvokerClientInterceptor代理拦截器对代理对象的方法拦截处理。
4.HttpInvokerClientInterceptor拦截对远程调用代理的方法调用:
当客户端通过HTTP请求调