1. 程式人生 > >hessian 序列化實現 初探

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.     serializer = (Serializer) _staticSerializerMap.get(cl);  
  6.     if (serializer != null)  
  7.       return serializer;  
  8.     if (_cachedSerializerMap != null) {  
  9.       synchronized (_cachedSerializerMap) {  
  10.     serializer = (Serializer) _cachedSerializerMap.get(cl);  
  11.       }  
  12.       if (serializer != null)  
  13.     return serializer;  
  14.     }  
  15.     for (int i = 0;  
  16.      serializer == null && _factories != null && i < _factories.size();  
  17.      i++) {  
  18.       AbstractSerializerFactory factory;  
  19.       factory = (AbstractSerializerFactory) _factories.get(i);  
  20.       serializer = factory.getSerializer(cl);  
  21.     }  
  22.     if (serializer != null) {  
  23.     }  
  24.     else if (JavaSerializer.getWriteReplace(cl) != null)  
  25.       serializer = new JavaSerializer(cl);  
  26.     else if (HessianRemoteObject.class.isAssignableFrom(cl))  
  27.       serializer = new RemoteSerializer();  
  28.     else if (BurlapRemoteObject.class.isAssignableFrom(cl))  
  29.       serializer = new RemoteSerializer();  
  30.     else if (Map.class.isAssignableFrom(cl)) {  
  31.       if (_mapSerializer == null)  
  32.     _mapSerializer = new MapSerializer();  
  33.       serializer = _mapSerializer;  
  34.     }  
  35.     else if (Collection.class.isAssignableFrom(cl)) {  
  36.       if (_collectionSerializer == null) {  
  37.     _collectionSerializer = new CollectionSerializer();  
  38.       }  
  39.       serializer = _collectionSerializer;  
  40.     }  
  41.     else if (cl.isArray())  
  42.       serializer = new ArraySerializer();  
  43.     else if (Throwable.class.isAssignableFrom(cl))  
  44.       serializer = new ThrowableSerializer(cl);  
  45.     else if (InputStream.class.isAssignableFrom(cl))  
  46.       serializer = new InputStreamSerializer();  
  47.     else if (Iterator.class.isAssignableFrom(cl))  
  48.       serializer = IteratorSerializer.create();  
  49.     else if (Enumeration.class.isAssignableFrom(cl))  
  50.       serializer = EnumerationSerializer.create();  
  51.     else if (Calendar.class.isAssignableFrom(cl))  
  52.       serializer = CalendarSerializer.create();  
  53.     else if (Locale.class.isAssignableFrom(cl))  
  54.       serializer = LocaleSerializer.create();  
  55.     else if (Enum.class.isAssignableFrom(cl))  
  56.       serializer = new EnumSerializer(cl);  
  57.     if (serializer == null)  
  58.       serializer = getDefaultSerializer(cl);  
  59.     if (_cachedSerializerMap == null)  
  60.       _cachedSerializerMap = new HashMap(8);  
  61.     synchronized (_cachedSerializerMap) {  
  62.       _cachedSerializerMap.put(cl, serializer);  
  63.     }  
  64.     return serializer;  
  65.   }  


在SerializerFactory中,實現了抽象類的getDeserializer方法,根據不同的需要被反序列化的類來獲得不同的反序列化工具,預設的反序列化工具類是JavaDeserializer 

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



下面我們來看一下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.     Serializer serializer;  
  9.     serializer = _serializerFactory.getSerializer(object.getClass());  
  10.     serializer.writeObject(object, this);  
  11.   }  



現在我們來看看AbstractSerializer,其中writeObject為必須在子類實現的方法,AbstractSerializer有17種子類實現,hessian根據不同的java物件型別來實現了不同的序列化工具類,其中預設的是JavaSerializer