hessian 序列化实现 初探

众所周知大名鼎鼎的开源remoting的框架hessian的速度是非常快的,有人做过测试:一个UserData类,有一个字符串属性,一个日期属性,一个double属性,分别用java,hessian来序列化一百万次,结果让人吃惊,不止是hessian序列化的速度要比java的快上一倍,而且hessian序列化后的字节数也要比java的少一倍.总是疑惑不解,为什么hessian的速度会那么快,这估计还是要归功于它的序列化的实现机制。兴趣上来了,决定看一下它是如何来实现它的序列化的。 

打开hessian源码,我们可以看到com.caucho.hessian.io这个包是hessian实现序列化与反序列化的核心包,从代码结构上我们不难发现,AbstractSerializerFactory,AbstractHessianOutput,AbstractSerializer,AbstractHessianInput,AbstractDeserializer是hessian实现序列化和反序列化的核心结构代码。 

首先我们来看下AbstractSerializerFactory,它有2个抽象方法 

根据类来决定用哪种序列化工具类 
Java代码   收藏代码
  1. abstract public Serializer getSerializer(Class cl)  
  2.   throws HessianProtocolException;  


根据类来决定用哪种反序列化工具类 
Java代码   收藏代码
  1. abstract public Deserializer getDeserializer(Class cl)  
  2.   throws HessianProtocolException;  


SerializerFactory继承AbstractSerializerFactory,而且在SerializerFactory有很多静态map用来存放类与序列化和反序列化工具类的映射,这样如果已经用过的序列化工具就可以直接拿出来用,不必再重新实例化工具类。 

Java代码   收藏代码
  1. private static HashMap _staticSerializerMap;  
  2. private static HashMap _staticDeserializerMap;  



在SerializerFactory中,实现了抽象类的getSerializer方法,根据不同的需要被序列化的类来获得不同的序列化工具,一共有17种序列化工具,hessian为不同的类型的java对象实现了不同的序列化工具,默认的序列化工具是JavaSerializer 
Java代码   收藏代码
  1. public Serializer getSerializer(Class cl)  
  2.     throws HessianProtocolException  
  3.   {  
  4.     Serializer serializer;  
  5.   
  6.     serializer = (Serializer) _staticSerializerMap.get(cl);  
  7.     if (serializer != null)  
  8.       return serializer;  
  9.   
  10.     if (_cachedSerializerMap != null) {  
  11.       synchronized (_cachedSerializerMap) {  
  12.     serializer = (Serializer) _cachedSerializerMap.get(cl);  
  13.       }  
  14.         
  15.       if (serializer != null)  
  16.     return serializer;  
  17.     }  
  18.   
  19.     for (int i = 0;  
  20.      serializer == null && _factories != null && i < _factories.size();  
  21.      i++) {  
  22.       AbstractSerializerFactory factory;  
  23.   
  24.       factory = (AbstractSerializerFactory) _factories.get(i);  
  25.   
  26.       serializer = factory.getSerializer(cl);  
  27.     }  
  28.   
  29.     if (serializer != null) {  
  30.     }  
  31.   
  32.     else if (JavaSerializer.getWriteReplace(cl) != null)  
  33.       serializer = new JavaSerializer(cl);  
  34.   
  35.     else if (HessianRemoteObject.class.isAssignableFrom(cl))  
  36.       serializer = new RemoteSerializer();  
  37.   
  38.     else if (BurlapRemoteObject.class.isAssignableFrom(cl))  
  39.       serializer = new RemoteSerializer();  
  40.   
  41.     else if (Map.class.isAssignableFrom(cl)) {  
  42.       if (_mapSerializer == null)  
  43.     _mapSerializer = new MapSerializer();  
  44.         
  45.       serializer = _mapSerializer;  
  46.     }  
  47.     else if (Collection.class.isAssignableFrom(cl)) {  
  48.       if (_collectionSerializer == null) {  
  49.     _collectionSerializer = new CollectionSerializer();  
  50.       }  
  51.   
  52.       serializer = _collectionSerializer;  
  53.     }  
  54.   
  55.     else if (cl.isArray())  
  56.       serializer = new ArraySerializer();  
  57.   
  58.     else if (Throwable.class.isAssignableFrom(cl))  
  59.       serializer = new ThrowableSerializer(cl);  
  60.   
  61.     else if (InputStream.class.isAssignableFrom(cl))  
  62.       serializer = new InputStreamSerializer();  
  63.   
  64.     else if (Iterator.class.isAssignableFrom(cl))  
  65.       serializer = IteratorSerializer.create();  
  66.   
  67.     else if (Enumeration.class.isAssignableFrom(cl))  
  68.       serializer = EnumerationSerializer.create();  
  69.       
  70.     else if (Calendar.class.isAssignableFrom(cl))  
  71.       serializer = CalendarSerializer.create();  
  72.       
  73.     else if (Locale.class.isAssignableFrom(cl))  
  74.       serializer = LocaleSerializer.create();  
  75.       
  76.     else if (Enum.class.isAssignableFrom(cl))  
  77.       serializer = new EnumSerializer(cl);  
  78.   
  79.     if (serializer == null)  
  80.       serializer = getDefaultSerializer(cl);  
  81.   
  82.     if (_cachedSerializerMap == null)  
  83.       _cachedSerializerMap = new HashMap(8);  
  84.   
  85.     synchronized (_cachedSerializerMap) {  
  86.       _cachedSerializerMap.put(cl, serializer);  
  87.     }  
  88.   
  89.     return serializer;  
  90.   }  


在SerializerFactory中,实现了抽象类的getDeserializer方法,根据不同的需要被反序列化的类来获得不同的反序列化工具,默认的反序列化工具类是JavaDeserializer 

Java代码   收藏代码
  1.  public Deserializer getDeserializer(Class cl)  
  2.    throws HessianProtocolException  
  3.  {  
  4.    Deserializer deserializer;  
  5.   
  6.    deserializer = (Deserializer) _staticDeserializerMap.get(cl);  
  7.    if (deserializer != null)  
  8.      return deserializer;  
  9.   
  10.    if (_cachedDeserializerMap != null) {  
  11.      synchronized (_cachedDeserializerMap) {  
  12. deserializer = (Deserializer) _cachedDeserializerMap.get(cl);  
  13.      }  
  14.        
  15.      if (deserializer != null)  
  16. return deserializer;  
  17.    }  
  18.   
  19.   
  20.    for (int i = 0;  
  21.  deserializer == null && _factories != null && i < _factories.size();  
  22.  i++) {  
  23.      AbstractSerializerFactory factory;  
  24.      factory = (AbstractSerializerFactory) _factories.get(i);  
  25.   
  26.      deserializer = factory.getDeserializer(cl);  
  27.    }  
  28.   
  29.    if (deserializer != null) {  
  30.    }  
  31.   
  32.    else if (Collection.class.isAssignableFrom(cl))  
  33.      deserializer = new CollectionDeserializer(cl);  
  34.   
  35.    else if (Map.class.isAssignableFrom(cl))  
  36.      deserializer = new MapDeserializer(cl);  
  37.      
  38.    else if (cl.isInterface())  
  39.      deserializer = new ObjectDeserializer(cl);  
  40.   
  41.    else if (cl.isArray())  
  42.      deserializer = new ArrayDeserializer(cl.getComponentType());  
  43.   
  44.    else if (Enumeration.class.isAssignableFrom(cl))  
  45.      deserializer = EnumerationDeserializer.create();  
  46.   
  47.    else if (Enum.class.isAssignableFrom(cl))  
  48.      deserializer = new EnumDeserializer(cl);  
  49.      
  50.    else  
  51.      deserializer = getDefaultDeserializer(cl);  
  52.   
  53.    if (_cachedDeserializerMap == null)  
  54.      _cachedDeserializerMap = new HashMap(8);  
  55.   
  56.    synchronized (_cachedDeserializerMap) {  
  57.      _cachedDeserializerMap.put(cl, deserializer);  
  58.    }  
  59.   
  60.    return deserializer;  
  61.  }  



下面我们来看一下HessianOutput,它继承AbstractHessianOutput成为序列化输出流的一种实现 
它会实现很多方法,用来做流输出为了标志某种特定含义的分隔,在这里就不详细说了,如: 
Java代码   收藏代码
  1. public void startCall()  
  2.   throws IOException  
  3. {  
  4.   os.write('c');  
  5.   os.write(0);  
  6.   os.write(1);  
  7. }  


需要注意的是方法,它会调用先serializerFactory根据类来获得serializer序列化工具类 
Java代码   收藏代码
  1. public void writeObject(Object object)  
  2.     throws IOException  
  3.   {  
  4.     if (object == null) {  
  5.       writeNull();  
  6.       return;  
  7.     }  
  8.   
  9.     Serializer serializer;  
  10.   
  11.     serializer = _serializerFactory.getSerializer(object.getClass());  
  12.   
  13.     serializer.writeObject(object, this);  
  14.   }  



现在我们来看看AbstractSerializer,其中writeObject为必须在子类实现的方法,AbstractSerializer有17种子类实现,hessian根据不同的java对象类型来实现了不同的序列化工具类,其中默认的是JavaSerializer 

Java代码   收藏代码
  1. abstract public class AbstractSerializer implements Serializer {  
  2.   protected static final Logger log = Logger.getLogger(AbstractSerializer.class.getName());  
  3.     
  4.   abstract public void writeObject(Object obj, AbstractHessianOutput out)  
  5.     throws IOException;  
  6. }  



以下是JavaSerializer的writeObject方法的实现,遍历java对象的数据成员,根据数据成员的类型来获得各自的FieldSerializer,一共有6中默认的FieldSerializer 
Java代码   收藏代码
  1.  public void writeObject(Object obj, AbstractHessianOutput out)  
  2.    throws IOException  
  3.  {  
  4.    if (out.addRef(obj)) {  
  5.      return;  
  6.    }  
  7.      
  8.    Class cl = obj.getClass();  
  9.   
  10.    try {  
  11.      if (_writeReplace != null) {  
  12. Object repl;  
  13.   
  14. if (_writeReplaceFactory != null)  
  15.   repl = _writeReplace.invoke(_writeReplaceFactory, obj);  
  16. else  
  17.   repl = _writeReplace.invoke(obj);  
  18.   
  19. out.removeRef(obj);  
  20.   
  21. out.writeObject(repl);  
  22.   
  23. out.replaceRef(repl, obj);  
  24.   
  25. return;  
  26.      }  
  27.    } catch (RuntimeException e) {  
  28.      throw e;  
  29.    } catch (Exception e) {  
  30.      // log.log(Level.FINE, e.toString(), e);  
  31.      throw new RuntimeException(e);  
  32.    }  
  33.   
  34.    int ref = out.writeObjectBegin(cl.getName());  
  35.   
  36.    if (ref < -1) {  
  37.      writeObject10(obj, out);  
  38.    }  
  39.    else {  
  40.      if (ref == -1) {  
  41. writeDefinition20(out);  
  42. out.writeObjectBegin(cl.getName());  
  43.      }  
  44.   
  45.      writeInstance(obj, out);  
  46.    }  
  47.  }  
  48.   
  49.  private void writeObject10(Object obj, AbstractHessianOutput out)  
  50.    throws IOException  
  51.  {  
  52.    for (int i = 0; i < _fields.length; i++) {  
  53.      Field field = _fields[i];  
  54.   
  55.      out.writeString(field.getName());  
  56.   
  57.      _fieldSerializers[i].serialize(out, obj, field);  
  58.    }  
  59.        
  60.    out.writeMapEnd();  
  61.  }  
  62.    
  63.  private void writeDefinition20(AbstractHessianOutput out)  
  64.    throws IOException  
  65.  {  
  66.    out.writeClassFieldLength(_fields.length);  
  67.   
  68.    for (int i = 0; i < _fields.length; i++) {  
  69.      Field field = _fields[i];  
  70.        
  71.      out.writeString(field.getName());  
  72.    }  
  73.  }  
  74.    
  75.  public void writeInstance(Object obj, AbstractHessianOutput out)  
  76.    throws IOException  
  77.  {  
  78.    for (int i = 0; i < _fields.length; i++) {  
  79.      Field field = _fields[i];  
  80.   
  81.      _fieldSerializers[i].serialize(out, obj, field);  
  82.    }  
  83.  }  



拿默认的FieldSerializer举例,还是调用AbstractHessianOutput的子类来writeObject,这个时候,肯定能找到相应的Serializer来做序列化 
Java代码   收藏代码
  1.  static class FieldSerializer {  
  2.    static final FieldSerializer SER = new FieldSerializer();  
  3.      
  4.    void serialize(AbstractHessianOutput out, Object obj, Field field)  
  5.      throws IOException  
  6.    {  
  7.      Object value = null;  
  8.   
  9.      try {  
  10. value = field.get(obj);  
  11.      } catch (IllegalAccessException e) {  
  12. log.log(Level.FINE, e.toString(), e);  
  13.      }  
  14.   
  15.      try {  
  16. out.writeObject(value);  
  17.      } catch (RuntimeException e) {  
  18. throw new RuntimeException(e.getMessage() + "\n Java field: " + field,  
  19.                e);  
  20.      } catch (IOException e) {  
  21. throw new IOExceptionWrapper(e.getMessage() + "\n Java field: " + field,  
  22.               e);  
  23.      }  
  24.    }  
  25.  }  



这样hessian的序列化架构已经都看完了,同理可以反推出hessian的反序列化机制。SerializerFactory可以根据需要被反序列化的类来获得反序列化工具类来做反序列化操作 

Java代码   收藏代码
  1. public Object readObject(AbstractHessianInput in)  
  2.   throws IOException  
  3. {  
  4.   Object obj = in.readObject();  
  5.   
  6.   String className = getClass().getName();  
  7.   
  8.   if (obj != null)  
  9.     throw error(className + ": unexpected object " + obj.getClass().getName() + " (" + obj + ")");  
  10.   else  
  11.     throw error(className + ": unexpected null value");  
  12. }  



HessianInput继承AbstractHessianInput实现方法readObject,在该方法中hessian就通过在序列化时做的标记来判断传输数据的类型等,根据传入的类来获得相应的反序列化工具来做反序列化操作,最终获得实例对象 
Java代码   收藏代码
  1. public Object readObject(Class cl)  
  2.     throws IOException  
  3.   {  
  4.     if (cl == null || cl == Object.class)  
  5.       return readObject();  
  6.       
  7.     int tag = read();  
  8.       
  9.     switch (tag) {  
  10.     case 'N':  
  11.       return null;  
  12.   
  13.     case 'M':  
  14.     {  
  15.       String type = readType();  
  16.   
  17.       // hessian/3386  
  18.       if ("".equals(type)) {  
  19.     Deserializer reader;  
  20.     reader = _serializerFactory.getDeserializer(cl);  
  21.   
  22.     return reader.readMap(this);  
  23.       }  
  24.       else {  
  25.     Deserializer reader;  
  26.     reader = _serializerFactory.getObjectDeserializer(type);  
  27.   
  28.         return reader.readMap(this);  
  29.       }  
  30.     }  
  31.   
  32.     case 'V':  
  33.     {  
  34.       String type = readType();  
  35.       int length = readLength();  
  36.         
  37.       Deserializer reader;  
  38.       reader = _serializerFactory.getObjectDeserializer(type);  
  39.         
  40.       if (cl != reader.getType() && cl.isAssignableFrom(reader.getType()))  
  41.         return reader.readList(this, length);  
  42.   
  43.       reader = _serializerFactory.getDeserializer(cl);  
  44.   
  45.       Object v = reader.readList(this, length);  
  46.   
  47.       return v;  
  48.     }  
  49.   
  50.     case 'R':  
  51.     {  
  52.       int ref = parseInt();  
  53.   
  54.       return _refs.get(ref);  
  55.     }  
  56.   
  57.     case 'r':  
  58.     {  
  59.       String type = readType();  
  60.       String url = readString();  
  61.   
  62.       return resolveRemote(type, url);  
  63.     }  
  64.     }  
  65.   
  66.     _peek = tag;  
  67.   
  68.     // hessian/332i vs hessian/3406  
  69.     //return readObject();  
  70.       
  71.     Object value = _serializerFactory.getDeserializer(cl).readObject(this);  
  72.   
  73.     return value;  
  74.   }  


看见网上还有把memcached的序列化实现改成用hessian的来实现,目前还没有做研究,有兴趣的朋友可以实践一下, 

说得比较多了,大体上的hessian的序列化与反序列化的机制就说到这里了,贴上来的代码不齐全,代码版本是hessian-3_2-snap-src,感兴趣的可以去hessian官网直接下载源码阅读。 

你可能感兴趣的:(hessian 序列化实现 初探)