1.Spring中,HTTPInvoker(HTTP调用器)是通过基于HTTP协议的分布式远程调用解决方案,和java RMI一样,HTTP调用器也需要使用java的对象序列化机制完成客户端和服务器端的通信。HTTP调用器的远程调用工作原理如下:
(1).客户端:
a.向服务器发送远程调用请求:
远程调用信息——>封装为远程调用对象——>序列化写入到远程调用HTTP请求中——>向服务器端发送。
b.接收服务器端返回的远程调用结果:
服务器端返回的远程调用结果HTTP响应——>反序列化为远程调用结果对象。
(2).服务器端:
a.接收客户端发送的远程调用请求:
客户端发送的远程调用HTTP请求——>反序列化为远程调用对象——>调用服务器端目标对象的目标方法处理。
b.向客户端返回远程调用结果:
服务器端目标对象方法的处理结果——>序列化写入远程调用结果HTTP响应中——>返回给客户端。
接下来我们将从客户端和服务器端分别分析HTTP调用器远程调用的具体实现。
2.HTTP调用器客户端配置:
使用HTTP调用器之前,首先需要对客户端其进行如下的配置:
- <!--客户端HTTP调用器代理-->
- <bean id=”proxy” class=”org.springframework.remoting.httpinvoker.HttpInvokerProxyFactoryBean”>
- <property name=”serviceUrl”>
- <value>http://yourhost:8080/远程调用URL</value>
- </property>
- <property name=”serviceInterface”>
- <value>远程调用服务接口全路径</value>
- </property>
- </bean>
- <bean id=”客户端bean” class=”客户端Bean全路径”>
- <property name=”remoteService”>
- <ref bean=”proxy”/>
- </property>
- </bean>
在HTTP调用器客户端代理HttpInvokerProxyFactoryBean中封装远程调用服务URL和服务接口,客户端程序通过HTTP调用代理可以调用实现了指定接口的目标服务端对象。
3.HttpInvokerProxyFactoryBean创建远程调用代理对象:
HTTP调用器客户端代理HttpInvokerProxyFactoryBean是一个实现了Spring FactoryBean接口的IoC容器,其作用是对远程服务客户端封装,源码如下:
- public class HttpInvokerProxyFactoryBean extends HttpInvokerClientInterceptor implements FactoryBean<Object> {
- //远程对象的代理
- 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请求调用远程调用代理的方法时,将会触发HttpInvokerClientInterceptor拦截器的invoke方法对当前的请求进行封装处理,将客户端的java对象序列化传输到服务器端,在远程服务器端执行完请求之后,又将处理结果java对象序列化返回给客户端。其源码如下: