Hessian源码学习(七)
今天重新看了一下Hessian的序列化类,发现了一个之前被自己忽略的地方,而这应该也是Hessian序列化较快的原因之一。
在大多数序列化类开始之前都有这么一段代码:
红色线框代表标识符,蓝色线框代表标识值
可以看到第二次序列化时,由于之前已经序列化该对象所以这次只是序列化该对象的一个标识,对照前面代码可以知道是0;
序列化我们说到这里,但是现在又有一个问题,在反序列化的时候是如何处理这些对象标识的呢? 那我们就来看下HessianInput.readOject(cl):
/** * 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 = read(); switch (tag) { case 'N': return null; case 'M': { String type = readType(); Deserializer reader; reader = _serializerFactory.getObjectDeserializer(type); if (cl != reader.getType() && cl.isAssignableFrom(reader.getType())) return reader.readMap(this); reader = _serializerFactory.getDeserializer(cl); return reader.readMap(this); } case 'V': { String type = readType(); int length = readLength(); Deserializer reader; reader = _serializerFactory.getObjectDeserializer(type); if (cl != reader.getType() && cl.isAssignableFrom(reader.getType())) return reader.readList(this, length); reader = _serializerFactory.getDeserializer(cl); Object v = reader.readList(this, length); return v; } // 如果是一个引用标识: case 'R': { // 读取标示的值(比如刚才例子那段代码就是0) int ref = parseInt(); // 返回对象 return _refs.get(ref); } case 'r': { String type = readType(); String url = readString(); return resolveRemote(type, url); } } _peek = tag; Object value = _serializerFactory.getDeserializer(cl).readObject(this); return value; }
也许大家会对_refs.get(ref)有点疑问,_refs其实是一个ArrayList,并且每当反序列化读取一个对象时(case 'M', case 'V'等等),就会把这个对象放入_refs中,那么当下次反序列化同一个对象时就可以直接从ArrayList中获取
这个特性我想也是Hessian序列化快的原因之一。