hessian在项目中使用了很久,一直没认真看过hessian是怎么实现的,想来这种rpc服务应该是动态代理加反射,走http协议而已,最近项目中出现了hessian调用第三方服务时,由于版本不同导致序列化不兼容的问题,调查过程中索性将hessian源码翻了一遍。
看的源码是4.0.7,hessian是caucho提供的,是resin的一部分,其实整个hessian工程代码一共没有多少,主要的就是client包和io包,还有个server包,主要server端用,里面就两个类,核心类是HessianSkeleton,稍后在说。
client包主要是client端使用的功能,里面就是动态代理和http连接等操作,io包则是处理序列化。
client包中有几个主要类,一个是HessianProxyFactory,主要是生成Proxy对象,create方法:
/**
* Creates a new proxy with the specified URL. The returned object
* is a proxy with the interface specified by api.
*
* <pre>
* String url = "http://localhost:8080/ejb/hello");
* HelloHome hello = (HelloHome) factory.create(HelloHome.class, url);
* </pre>
*
* @param api the interface the proxy class needs to implement
* @param url the URL where the client object is located.
*
* @return a proxy to the object with the specified interface.
*/
public Object create(Class<?> api, URL url, ClassLoader loader)
{
if (api == null)
throw new NullPointerException("api must not be null for HessianProxyFactory.create()");
InvocationHandler handler = null;
handler = new HessianProxy(url, this, api);
return Proxy.newProxyInstance(loader, new Class[] { api, HessianRemoteObject.class }, handler);
}
这个方法没啥特殊,new了一个HessianProxy,其是个InvocationHandler,直接看invoke方法:
/**
* Handles the object invocation.
*
* @param proxy the proxy object to invoke
* @param method the method to call
* @param args the arguments to the proxy object
*/
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
String mangleName;
// 把method name 和method param 拼成一个唯一的mangleName缓存起来
synchronized (_mangleMap) {
mangleName = _mangleMap.get(method);
}
if (mangleName == null) {
String methodName = method.getName();
Class<?>[] params = method.getParameterTypes();
// equals and hashCode are special cased
// 一些方法不用走服务器端
if (methodName.equals("equals") && params.length == 1 && params[0].equals(Object.class)) {
Object value = args[0];
if (value == null || !Proxy.isProxyClass(value.getClass()))
return Boolean.FALSE;
Object proxyHandler = Proxy.getInvocationHandler(value);
if (!(proxyHandler instanceof HessianProxy))
return Boolean.FALSE;
HessianProxy handler = (HessianProxy) proxyHandler;
return new Boolean(_url.equals(handler.getURL()));
} else if (methodName.equals("hashCode") && params.length == 0)
return new Integer(_url.hashCode());
else if (methodName.equals("getHessianType"))
return proxy.getClass().getInterfaces()[0].getName();
else if (methodName.equals("getHessianURL"))
return _url.toString();
else if (methodName.equals("toString") && params.length == 0)
return "HessianProxy[" + _url + "]";
// 如果可以overload就拼参数
if (!_factory.isOverloadEnabled())
mangleName = method.getName();
else
mangleName = mangleName(method);
synchronized (_mangleMap) {
_mangleMap.put(method, mangleName);
}
}
InputStream is = null;
HessianConnection conn = null;
try {
if (log.isLoggable(Level.FINER))
log.finer("Hessian[" + _url + "] calling " + mangleName);
// 序列化并与服务器通信,成功吧conn返回来,不成功在内部就处理了
conn = sendRequest(mangleName, args);
is = conn.getInputStream();
if (log.isLoggable(Level.FINEST)) {
PrintWriter dbg = new PrintWriter(new LogWriter(log));
HessianDebugInputStream dIs = new HessianDebugInputStream(is, dbg);
dIs.startTop2();
is = dIs;
}
AbstractHessianInput in;
int code = is.read();
if (code == 'H') {
int major = is.read();
int minor = is.read();
// 取AbstractHessianInput,是Hessian2Input实例,里面也是持有SerializerFactory,SerializerFactory里也是ContextSerializerFactory,
in = _factory.getHessian2Input(is);
// 反序列化
Object value = in.readReply(method.getReturnType());
return value;
} else if (code == 'r') {
int major = is.read();
int minor = is.read();
in = _factory.getHessianInput(is);
in.startReplyBody();
Object value = in.readObject(method.getReturnType());
if (value instanceof InputStream) {
value = new ResultInputStream(conn, is, in, (InputStream) value);
is = null;
conn = null;
} else
in.completeReply();
return value;
} else
throw new HessianProtocolException("'" + (char) code + "' is an unknown code");
} catch (HessianProtocolException e) {
throw new HessianRuntimeException(e);
} finally {
try {
if (is != null)
is.close();
} catch (Exception e) {
log.log(Level.FINE, e.toString(), e);
}
try {
if (conn != null)
conn.destroy();
} catch (Exception e) {
log.log(Level.FINE, e.toString(), e);
}
}
}
/**
* Sends the HTTP request to the Hessian connection.
*/
protected HessianConnection sendRequest(String methodName, Object[] args) throws IOException {
HessianConnection conn = null;
// 默认是HessianURLConnectionFactory,在open时openConnection,并且设置timeout等属性,然后new一个HessianURLConnection返回,HessianURLConnection真正持有并使用的还是HttpURLConnection
conn = _factory.getConnectionFactory().open(_url);
boolean isValid = false;
try {
// 设置Content-Type等Header属性
addRequestHeaders(conn);
OutputStream os = null;
try {
os = conn.getOutputStream();
} catch (Exception e) {
throw new HessianRuntimeException(e);
}
if (log.isLoggable(Level.FINEST)) {
PrintWriter dbg = new PrintWriter(new LogWriter(log));
HessianDebugOutputStream dOs = new HessianDebugOutputStream(os, dbg);
dOs.startTop2();
os = dOs;
}
// 得到的AbstractHessianOutput用于序列化,默认reques使用HessianOutput而不是Hessian2Output,out里面new了一个SerializerFactory,SerializerFactory实例化时创建的一个ContextSerializerFactory
AbstractHessianOutput out = _factory.getHessianOutput(os);
// 这里序列化
out.call(methodName, args);
out.flush();
// 这里完成与服务器通信,并对返回状态码验证,如果验证通过返回conn,验证不通过直接该关资源关资源,该抛异常抛异常
conn.sendRequest();
isValid = true;
return conn;
} finally {
if (!isValid && conn != null)
conn.destroy();
}
}
/**
* Writes a complete method call.
*/
public void call(String method, Object []args)
throws IOException
{
int length = args != null ? args.length : 0;
// 这里先放’c’和’m’,’m'方法名
startCall(method, length);
// 然后在循环每个参数
for (int i = 0; i < length; i++)
writeObject(args[i]);
// 用’z'结尾
completeCall();
}
writeObject就是根据各个参数的类型,找出对应的序列化类,典型工厂
/**
* Writes any object to the output stream.
*/
public void writeObject(Object object)
throws IOException
{
if (object == null) {
writeNull();
return;
}
Serializer serializer;
// 针对每个参数的类型取得相应的序列化类,SerializerFactory的getSerializer()
serializer = _serializerFactory.getSerializer(object.getClass());
// 不同类型的Serializer对应不同的序列化方法,BasicSerializer解决了很多比较基本的类型
serializer.writeObject(object, this);
}
/**
* Returns the serializer for a class.
*
* @param cl the class of the object that needs to be serialized.
*
* @return a serializer object for the serialization.
*/
public Serializer getSerializer(Class cl)
throws HessianProtocolException
{
Serializer serializer;
if (_cachedSerializerMap != null) {
serializer = (Serializer) _cachedSerializerMap.get(cl);
if (serializer != null)
return serializer;
}
// 选择使用哪个serializer,然后缓存
<span style="white-space:pre"> </span>serializer = loadSerializer(cl);
if (_cachedSerializerMap == null)
_cachedSerializerMap = new ConcurrentHashMap(8);
_cachedSerializerMap.put(cl, serializer);
return serializer;
}
protected Serializer loadSerializer(Class cl) throws HessianProtocolException {
Serializer serializer = null;
for (int i = 0; _factories != null && i < _factories.size(); i++) {
AbstractSerializerFactory factory;
factory = (AbstractSerializerFactory) _factories.get(i);
serializer = factory.getSerializer(cl);
if (serializer != null)
return serializer;
}
// 这里ContextSerializerFactory中预置了一些类型,找不到的再向下找
serializer = _contextFactory.getSerializer(cl.getName());
if (serializer != null)
return serializer;
ClassLoader loader = cl.getClassLoader();
if (loader == null)
loader = _systemClassLoader;
// 对于自定义的类型,这里重新create一个ContextSerializerFactory,然后在取自定义的序列化器,没自定义的,一般就Default了
ContextSerializerFactory factory = null;
factory = ContextSerializerFactory.create(loader);
serializer = factory.getCustomSerializer(cl);
if (serializer != null)
return serializer;
if (HessianRemoteObject.class.isAssignableFrom(cl))
return new RemoteSerializer();
else if (BurlapRemoteObject.class.isAssignableFrom(cl))
return new RemoteSerializer();
else if (JavaSerializer.getWriteReplace(cl) != null) {
Serializer baseSerializer = getDefaultSerializer(cl);
return new WriteReplaceSerializer(cl, _loader, baseSerializer);
}
else if (Map.class.isAssignableFrom(cl)) {
if (_mapSerializer == null)
_mapSerializer = new MapSerializer();
return _mapSerializer;
} else if (Collection.class.isAssignableFrom(cl)) {
if (_collectionSerializer == null) {
_collectionSerializer = new CollectionSerializer();
}
return _collectionSerializer;
}
else if (cl.isArray())
return new ArraySerializer();
else if (Throwable.class.isAssignableFrom(cl))
return new ThrowableSerializer(cl, getClassLoader());
else if (InputStream.class.isAssignableFrom(cl))
return new InputStreamSerializer();
else if (Iterator.class.isAssignableFrom(cl))
return IteratorSerializer.create();
else if (Calendar.class.isAssignableFrom(cl))
return CalendarSerializer.SER;
else if (Enumeration.class.isAssignableFrom(cl))
return EnumerationSerializer.create();
else if (Enum.class.isAssignableFrom(cl))
return new EnumSerializer(cl);
else if (Annotation.class.isAssignableFrom(cl))
return new AnnotationSerializer(cl);
return getDefaultSerializer(cl);
}
默认Serializer是这个,有UnsafeSerializer和JavaSerializer
/**
* Returns the default serializer for a class that isn't matched
* directly. Application can override this method to produce
* bean-style serialization instead of field serialization.
*
* @param cl the class of the object that needs to be serialized.
*
* @return a serializer object for the serialization.
*/
protected Serializer getDefaultSerializer(Class cl)
{
if (_defaultSerializer != null)
return _defaultSerializer;
if (! Serializable.class.isAssignableFrom(cl)
&& ! _isAllowNonSerializable) {
throw new IllegalStateException("Serialized class " + cl.getName() + " must implement java.io.Serializable");
}
if (_isEnableUnsafeSerializer
&& JavaSerializer.getWriteReplace(cl) == null) {
return UnsafeSerializer.create(cl);
}
else
return JavaSerializer.create(cl);
}
之后回到invoke接着看,执行完了
conn = sendRequest(mangleName,args);
取得了返回值后开始反序列化:重点看
Object value=
in.readReply(method.getReturnType());
in是Hessian2Input实例,看下Hessian2Input的readReply()方法:
/**
* Reads a reply as an object.
* If the reply has a fault, throws the exception.
*/
@Override
public Object readReply(Class expectedClass) throws Throwable {
int tag = read();
if (tag == 'R')
return readObject(expectedClass);
else if (tag == 'F') {
HashMap map = (HashMap) readObject(HashMap.class);
throw prepareFault(map);
} else {
StringBuilder sb = new StringBuilder();
sb.append((char) tag);
try {
int ch;
while ((ch = read()) >= 0) {
sb.append((char) ch);
}
} catch (IOException e) {
log.log(Level.FINE, e.toString(), e);
}
throw error("expected hessian reply at " + codeName(tag) + "\n" + sb);
}
}
然后是具体实施的readObject,也是根据type取对应的反序列化类,然后操作:
/**
* Reads an object from the input stream with an expected type.
*/
public Object readObject(Class cl) throws IOException {
if (cl == null || cl == Object.class)
return readObject();
int tag = _offset < _length ? (_buffer[_offset++] & 0xff) : read();
switch (tag) {
case 'N':
return null;
case 'H': {
Deserializer reader = findSerializerFactory().getDeserializer(cl);
return reader.readMap(this);
}
case 'M': {
String type = readType();
// hessian/3bb3
if ("".equals(type)) {
Deserializer reader;
reader = findSerializerFactory().getDeserializer(cl);
return reader.readMap(this);
} else {
Deserializer reader;
reader = findSerializerFactory().getObjectDeserializer(type, cl);
return reader.readMap(this);
}
}
case 'C': {
// 自定义类型走到了这里
readObjectDefinition(cl);
// 再取
return readObject(cl);
}
case 0x60:
case 0x61:
case 0x62:
case 0x63:
case 0x64:
case 0x65:
case 0x66:
case 0x67:
case 0x68:
case 0x69:
case 0x6a:
case 0x6b:
case 0x6c:
case 0x6d:
case 0x6e:
case 0x6f: {
int ref = tag - 0x60;
int size = _classDefs.size();
if (ref < 0 || size <= ref)
throw new HessianProtocolException("'" + ref + "' is an unknown class definition");
ObjectDefinition def = _classDefs.get(ref);
// 再生成instance
return readObjectInstance(cl, def);
}
case 'O': {
int ref = readInt();
int size = _classDefs.size();
if (ref < 0 || size <= ref)
throw new HessianProtocolException("'" + ref + "' is an unknown class definition");
ObjectDefinition def = _classDefs.get(ref);
return readObjectInstance(cl, def);
}
case BC_LIST_VARIABLE: {
String type = readType();
Deserializer reader;
reader = findSerializerFactory().getListDeserializer(type, cl);
Object v = reader.readList(this, -1);
return v;
}
case BC_LIST_FIXED: {
String type = readType();
int length = readInt();
Deserializer reader;
reader = findSerializerFactory().getListDeserializer(type, cl);
Object v = reader.readLengthList(this, length);
return v;
}
case 0x70:
case 0x71:
case 0x72:
case 0x73:
case 0x74:
case 0x75:
case 0x76:
case 0x77: {
int length = tag - 0x70;
String type = readType();
Deserializer reader;
reader = findSerializerFactory().getListDeserializer(type, cl);
Object v = reader.readLengthList(this, length);
return v;
}
case BC_LIST_VARIABLE_UNTYPED: {
Deserializer reader;
reader = findSerializerFactory().getListDeserializer(null, cl);
Object v = reader.readList(this, -1);
return v;
}
case BC_LIST_FIXED_UNTYPED: {
int length = readInt();
Deserializer reader;
reader = findSerializerFactory().getListDeserializer(null, cl);
Object v = reader.readLengthList(this, length);
return v;
}
case 0x78:
case 0x79:
case 0x7a:
case 0x7b:
case 0x7c:
case 0x7d:
case 0x7e:
case 0x7f: {
int length = tag - 0x78;
Deserializer reader;
reader = findSerializerFactory().getListDeserializer(null, cl);
Object v = reader.readLengthList(this, length);
return v;
}
case BC_REF: {
int ref = readInt();
return _refs.get(ref);
}
}
if (tag >= 0)
_offset--;
// hessian/3b2i vs hessian/3406
// return readObject();
Object value = findSerializerFactory().getDeserializer(cl).readObject(this);
return value;
}
大部分都是找到对应的Deserializer,然后返序列化返回,但如果返回值是个自定义类型,会稍微复杂,到了’C’, readObjectDefinition(cl);
/**
* Reads an object definition:
*
* <pre>
* O string <int> (string)* <value>*
* </pre>
*/
private void readObjectDefinition(Class<?> cl)
throws IOException
{
String type = readString();
int len = readInt();
// 这里还是SerializerFactory
SerializerFactory factory = findSerializerFactory();
// 里面辗转通过SerializerFactory的getObjectDeserializer,调到SerializerFactory的getDeserializer
Deserializer reader = factory.getObjectDeserializer(type, null);
// 这里是UnsafeDeserializer$FieldDeserializer的数组,然后根据每个属性的id取对应的FieldDeserializer
Object []fields = reader.createFields(len);
String []fieldNames = new String[len];
for (int i = 0; i < len; i++) {
String name = readString();
fields[i] = reader.createField(name);
fieldNames[i] = name;
}
ObjectDefinition def
= new ObjectDefinition(type, reader, fields, fieldNames);
_classDefs.add(def);
}
factory.getObjectDeserializer(type,null)里辗转调用,最后会调用到SerializerFactory的getDeserializer:
/**
* Reads the object as a map.
*/
public Deserializer getObjectDeserializer(String type, Class cl)
throws HessianProtocolException
{
Deserializer reader = getObjectDeserializer(type);
if (cl == null
|| cl.equals(reader.getType())
|| cl.isAssignableFrom(reader.getType())
|| reader.isReadResolve()
|| HessianHandle.class.isAssignableFrom(reader.getType())) {
return reader;
}
if (log.isLoggable(Level.FINE)) {
log.fine("hessian: expected deserializer '" + cl.getName() + "' at '" + type + "' ("
+ reader.getType().getName() + ")");
}
return getDeserializer(cl);
}
/**
* Reads the object as a map.
*/
public Deserializer getObjectDeserializer(String type)
throws HessianProtocolException
{
Deserializer deserializer = getDeserializer(type);
if (deserializer != null)
return deserializer;
else if (_hashMapDeserializer != null)
return _hashMapDeserializer;
else {
_hashMapDeserializer = new MapDeserializer(HashMap.class);
return _hashMapDeserializer;
}
}
到通过String取Serializer:
/**
* Returns a deserializer based on a string type.
*/
public Deserializer getDeserializer(String type)
throws HessianProtocolException
{
if (type == null || type.equals(""))
return null;
Deserializer deserializer;
if (_cachedTypeDeserializerMap != null) {
synchronized (_cachedTypeDeserializerMap) {
deserializer = (Deserializer) _cachedTypeDeserializerMap.get(type);
}
if (deserializer != null)
return deserializer;
}
deserializer = (Deserializer) _staticTypeMap.get(type);
if (deserializer != null)
return deserializer;
if (type.startsWith("[")) {
Deserializer subDeserializer = getDeserializer(type.substring(1));
if (subDeserializer != null)
deserializer = new ArrayDeserializer(subDeserializer.getType());
else
deserializer = new ArrayDeserializer(Object.class);
}
else {
try {
Class cl = Class.forName(type, false, _loader);
// 最终还是通过class类型取
deserializer = getDeserializer(cl);
} catch (Exception e) {
log.warning("Hessian/Burlap: '" + type + "' is an unknown class in " + _loader + ":\n" + e);
log.log(Level.FINER, e.toString(), e);
}
}
if (deserializer != null) {
if (_cachedTypeDeserializerMap == null)
_cachedTypeDeserializerMap = new HashMap(8);
synchronized (_cachedTypeDeserializerMap) {
_cachedTypeDeserializerMap.put(type, deserializer);
}
}
return deserializer;
}
/**
* Returns the deserializer for a class.
*
* @param cl the class of the object that needs to be deserialized.
*
* @return a deserializer object for the serialization.
*/
public Deserializer getDeserializer(Class cl)
throws HessianProtocolException
{
Deserializer deserializer;
if (_cachedDeserializerMap != null) {
deserializer = (Deserializer) _cachedDeserializerMap.get(cl);
if (deserializer != null)
return deserializer;
}
// 和序列化时一样,根据类型取序列化对象
deserializer = loadDeserializer(cl);
if (_cachedDeserializerMap == null)
_cachedDeserializerMap = new ConcurrentHashMap(8);
_cachedDeserializerMap.put(cl, deserializer);
return deserializer;
}
这里反序列化和序列化类似:
protected Deserializer loadDeserializer(Class cl)
throws HessianProtocolException
{
Deserializer deserializer = null;
for (int i = 0;
deserializer == null && _factories != null && i < _factories.size();
i++) {
AbstractSerializerFactory factory;
factory = (AbstractSerializerFactory) _factories.get(i);
deserializer = factory.getDeserializer(cl);
}
if (deserializer != null)
return deserializer;
// XXX: need test
deserializer = _contextFactory.getDeserializer(cl.getName());
if (deserializer != null)
return deserializer;
ContextSerializerFactory factory = null;
if (cl.getClassLoader() != null)
factory = ContextSerializerFactory.create(cl.getClassLoader());
else
factory = ContextSerializerFactory.create(_systemClassLoader);
deserializer = factory.getCustomDeserializer(cl);
if (deserializer != null)
return deserializer;
if (Collection.class.isAssignableFrom(cl))
deserializer = new CollectionDeserializer(cl);
else if (Map.class.isAssignableFrom(cl))
deserializer = new MapDeserializer(cl);
else if (Annotation.class.isAssignableFrom(cl))
deserializer = new AnnotationDeserializer(cl);
else if (cl.isInterface())
deserializer = new ObjectDeserializer(cl);
else if (cl.isArray())
deserializer = new ArrayDeserializer(cl.getComponentType());
else if (Enumeration.class.isAssignableFrom(cl))
deserializer = EnumerationDeserializer.create();
else if (Enum.class.isAssignableFrom(cl))
deserializer = new EnumDeserializer(cl);
else if (Class.class.equals(cl))
deserializer = new ClassDeserializer(_loader);
else
deserializer = getDefaultDeserializer(cl);
return deserializer;
}
再回到Hessian2Input的readObject的方法继续看这里:
case 'C':
{
{
readObjectDefinition(cl);
returnreadObject(cl);
}
在调readObject(),这次会生成instance:
private Object readObjectInstance(Class<?> cl,
ObjectDefinition def)
throws IOException
{
String type = def.getType();
Deserializer reader = def.getReader();
Object []fields = def.getFields();
SerializerFactory factory = findSerializerFactory();
if (cl != reader.getType() && cl != null) {
reader = factory.getObjectDeserializer(type, cl);
return reader.readObject(this, def.getFieldNames());
}
else {
// UnsafeDeserializer的readObject
return reader.readObject(this, fields);
}
}
UnsafeDeserializer的readObject:
@Override
public Object readObject(AbstractHessianInput in,
Object []fields)
throws IOException
{
try {
Object obj = instantiate();
return readObject(in, obj, (FieldDeserializer []) fields);
} catch (IOException e) {
throw e;
} catch (RuntimeException e) {
throw e;
} catch (Exception e) {
throw new IOExceptionWrapper(_type.getName() + ":" + e.getMessage(), e);
}
}
public Object readObject(AbstractHessianInput in,
Object obj,
FieldDeserializer []fields)
throws IOException
{
try {
int ref = in.addRef(obj);
// 按照每种Field的类型的Deserializer挨个处理
for (FieldDeserializer reader : fields) {
reader.deserialize(in, obj);
}
Object resolve = resolve(in, obj);
if (obj != resolve)
in.setRef(ref, resolve);
return resolve;
} catch (IOException e) {
throw e;
} catch (Exception e) {
throw new IOExceptionWrapper(obj.getClass().getName() + ":" + e, e);
}
}
将返回值反序列化完,client端流程就走完了,服务端在单独分析。