hessian_简介

来源:互联网 发布:西田亚沙子 知乎 编辑:程序博客网 时间:2024/05/29 16:26
一.Binary-RPC协议
Binary-RPC 是一种和 RMI 类似的远程调用的协议,它和 RMI 的不同之处在于它以标准的二进制格式来定义请求的信息 ( 请求的对象、方法、参数等 ) ,这样做的好处是什么呢,就是在跨语言通讯的时候也可以使用。
来看下 Binary -RPC 协议的一次远程通信过程:
1 、客户端发起请求,按照 Binary -RPC 协议将请求信息进行填充;
2 、填充完毕后将二进制格式文件转化为流,通过传输协议进行传输;
3 、接收到在接收到流后转换为二进制格式文件,按照 Binary -RPC 协议获取请求的信息并进行处理;

4 、处理完毕后将结果按照 Binary -RPC 协议写入二进制格式文件中并返回。

二.Hessian
Hessian 是由 caucho 提供的一个基于 binary-RPC 实现的远程通讯 library 。
1 、是基于什么协议实现的?
基于 Binary-RPC 协议实现。
2 、怎么发起请求?
需通过 Hessian 本身提供的 API 来发起请求。
3 、怎么将请求转化为符合协议的格式的?
Hessian 通过其自定义的串行化机制将请求信息进行序列化,产生二进制流。
4 、使用什么传输协议传输?
Hessian 基于 Http 协议进行传输。
5 、响应端基于什么机制来接收请求?
响应端根据 Hessian 提供的 API 来接收请求。
6 、怎么将流还原为传输格式的?
Hessian 根据其私有的串行化机制来将请求信息进行反序列化,传递给使用者时已是相应的请求信息对象了。
7 、处理完毕后怎么回应?

处理完毕后直接返回, hessian 将结果对象进行序列化,传输至调用端。


三.Hessian源码

String methodName = method.getName();// 取得方法名Object value = args[0]; // 取得传入参数conn = sendRequest(mangleName, args) ; // 通过该方法和服务器端取得连接httpConn = (HttpURLConnection) conn;code = httpConn.getResponseCode(); // 发出请求// 等待服务器端返回相应…………is = conn.getInputStream();Object value = in.readObject(method.getReturnType()); // 取得返回值URLConnection conn = _factory.openConnection(_url); // 创建 URLConnectionOutputStream os = conn.getOutputStream();AbstractHessianOutput out = _factory.getHessianOutput(os); // 封装为 hessian 自己的输入输出 APIout.call(methodName, args);return conn;

1.客户端发送请求
Hessian 的这个远程过程调用,完全使用动态代理来实现的。有客户端可以看出。
除去 spring 对其的封装,客户端主要是通过 HessianProxyFactory  create 方法就是创建接口的代理类,该类实现了接口, JDK  proxy 类会自动用 InvocationHandler 的实现类(该类在 Hessian 中表现为 HessianProxy )的 invoke 方法体来填充所生成代理类的方法体。
根据 serviceUrl 和 serviceInterface 创建代理。
HessianProxyFactoryBean 类
HessianClientInterceptor 类 createHessianProxy(HessianProxyFactory proxyFactory)
HessianProxyFactory 类 public Object create(Class api, String urlName)
客户端调用 hessian 服务时:
HessianProxy 类的 invoke(Object proxy, Method method, Object []args) 方法
HessianProxy 类的 URLConnection sendRequest(String methodName, Object []args) 方法:
2.服务器端相应请求有多种处理方式:

2.1

服务器端接受并处理请求
com.caucho.hessian.server.HessianServlet

2.2 hessian 与 spring 结合使用

或者继承该类的类去处理,这是hessian中自带的servlet
org.springframework.remoting.caucho.HessianServiceExporter
处理相应的请求

2.2.1 处理步骤

2.2.1.1 HessianServiceExporter 

(H  hessianExporter) invoke(request.getInputStream(), response.getOutputStream());
2.2.1.2  HessianExporter 
(He hessian2SkeletonInvoker) this.skeletonInvoker.invoke(inputStream, outputStream);
2.2.1.3 Hessian2SkeletonInvoker 
Hes Hesian2Input in = new Hessian2Input(isToUse);in.setSerializerFactory(this.serializerFactory);AbstractHessianOutput out = null;int major = in.read();int minor = in.read();out = new Hessian2Output(osToUse);out = new HessianOutput(osToUse);out.setSerializerFactory(this.serializerFactory);(HessianSkeleton) this.skeleton.invoke(in, out);
2.2.1.4 HessianSkeleton 
String methodName = in.readMethod();Method method = getMethod(methodName);
读取方法参数:
Class []args = method.getParameterTypes();Object []values = new Object[args.length];
执行相应方法并取得结果
result = method.invoke(service, values);
结果写入到输出流

out.writeObject(result);

将输入输出封转化为转化为 Hessian 特有的 Hessian2Input  Hessian2Output



四.Hessian的序列化和反序列化的实现
com.caucho.hessian.io
是hessian实现序列化和反序列化的核心包
根据类来决定用哪种序列化工具类
abstract public Serializer getSerializer(Class cl) throws HessianProtocolException;
根据类来决定用哪种反序列化工具类
abstract public Deserializer getDeserializer(Class cl) throws HessianProtocolException;
2. SerializerFactory 继承 AbstractSerializerFactory 
读取方法名:

AbstractSerializerFactory  AbstractHessianOutput  AbstractSerializer  AbstractHessianInput AbstractDeserializer  hessian 实现序列化和反序列化的核心结构代码。

1.AbstractSerializerFactory 
 SerializerFactory 中,实现了抽象类的 getSerializer 方法,根据不同的需要被序列化的类来获得不同的序列化工具,一共有 17 种序列化工具, hessian 为不同的类型的 java 对象实现了不同的序列化工具,默认的序列化工具是 JavaSerializer 
 SerializerFactory 中,也实现了抽象类的 getDeserializer 方法,根据不同的需要被反序列化的类来获得不同的反序列化工具,默认的反序列化工具类是 JavaDeserializer 
3.HessianOutput 继承 AbstractHessianOutput 成为序列化输出流的一种实现
它会实现很多方法,用来做流输出
需要注意的是方法,它会先调用 serializerFactory 根据类来获得 serializer 序列化工具类

hessian序列化和反序列化的速度很快,序列化后的字节也很少