《hessian序列化.pdf》由会员分享,可在线阅读,更多相关《hessian序列化.pdf(18页珍藏版)》请在taowenge.com淘文阁网|工程机械CAD图纸|机械工程制图|CAD装配图下载|SolidWorks_CaTia_CAD_UG_PROE_设计图分享下载上搜索。
1、hessian 序列化 众所周知大名鼎鼎的开源 remoting 的框架 hessian 的速度是非常快的,有人做过测试:一个 UserData 类,有一个字符串属性,一个日期属性,一个 double 属性,分别用 java,hessian 来序列化一百万次,结果让人吃惊,不止是 hessian 序列化的速度要比 java 的快上一倍,而且 hessian 序列化后的字节数也要比 java 的少一倍.总是疑惑不解,为什么 hessian 的速度会那么快,这估计还是要归功于它的序列化的实现机制。兴趣上来了,决定看一下它是如何来实现它的序列化的。打开 hessian 源码,我们可以看到 com.c
2、aucho.hessian.io这个包是 hessian实现序列化与反序列化的核心包,从代码结构上我们不难发现,AbstractSerializerFactory,AbstractHessianOutput,AbstractSerializer,AbstractHessianInput,AbstractDeserializer是 hessian实现序列化和反序列化的核心结构代码。首先我们来看下 AbstractSerializerFactory,它有 2 个抽象方法 根据类来决定用哪种序列化工具类 Java 代码 1.abstract public Serializer getSerializ
3、er(Class cl)2.throws HessianProtocolException;根据类来决定用哪种反序列化工具类 Java 代码 1.abstract public Deserializer getDeserializer(Class cl)2.throws HessianProtocolException;SerializerFactory继承 AbstractSerializerFactory,而且在 SerializerFactory 有很多静态 map 用来存放类与序列化和反序列化工具类的映射,这样如果已经用过的序列化工具就可以直接拿出来用,不必再重新实例化工具类。Java
4、 代码 1.private static HashMap _staticSerializerMap;2.private static HashMap _staticDeserializerMap;在 SerializerFactory 中,实现了抽象类的 getSerializer 方法,根据不同的需 要被序列化的类来获得不同的序列化工具,一共有 17 种序列化工具,hessian 为不同的类型的 java 对象实现了不同的序列化工具,默认的序列化工具是 JavaSerializer Java 代码 1.public Serializer getSerializer(Class cl)2.th
5、rows 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.if(serializer
6、!=null)15.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(J
7、avaSerializer.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.isAssi
8、gnableFrom(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.els
9、e 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.serialize
10、r=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.crea
11、te();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,seri
12、alizer);87.88.89.return serializer;90.在 SerializerFactory 中,实现了抽象类的 getDeserializer 方法,根据不同的 需要被反序列化的类来获得不同的反序列化工具,默认的反序列化工具类是 JavaDeserializer Java 代码 1.public Deserializer getDeserializer(Class cl)2.throws HessianProtocolException 3.4.Deserializer deserializer;5.deserializer=(Deserializer)_staticD
13、eserializerMap.get(cl)6.;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.deserialize
14、r=null&_factories!=null&i _factories.s ize();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 Coll
15、ectionDeserializer(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()deserializer=new ArrayDeserializer(cl.getComponentType()42.);43.44.else if(Enumeration.class.i
16、sAssignableFrom(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.synchron
17、ized(_cachedDeserializerMap)57._cachedDeserializerMap.put(cl,deserializer);58.59.60.return deserializer;61.下面我们来看一下 HessianOutput,它继承 AbstractHessianOutput 成为序列化输出流的一种实现 它会实现很多方法,用来做流输出为了标志某种特定含义的分隔,在这里就不详细说了,如:Java 代码 1.public void startCall()2.throws IOException 3.os.write(c);4.5.os.write(0);6.os.
18、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.getCla ss();12.13.serializer.writeOb
19、ject(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(Abstract S
20、erializer.class.getName();3.4.abstract public void writeObject(Object obj,AbstractHessianO utput out)5.throws IOException;6.以下是 JavaSerializer 的 writeObject 方法的实现,遍历 java 对象的数据成员,根据数据成员的类型来获得各自的 FieldSerializer,一共有 6 中默认的 FieldSerializer Java 代码 1.public void writeObject(Object obj,AbstractHessianOu
21、tput 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);2
22、0.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);3
23、8.39.else 40.if(ref=-1)41.writeDefinition20(out);42.out.writeObjectBegin(cl.getName();43.44.writeInstance(obj,out);45.46.47.48.49.private void writeObject10(Object obj,AbstractHessianOutput o ut)50.throws IOException 51.52.for(int i=0;i _fields.length;i+)53.Field field=_fieldsi;54.55.out.writeString
24、(field.getName();56.57._fieldSerializersi.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=_fieldsi;70.71.ou
25、t.writeString(field.getName();72.73.74.75.public void writeInstance(Object obj,AbstractHessianOutput ou t)76.throws IOException 77.78.for(int i=0;i _fields.length;i+)79.Field field=_fieldsi;80.81._fieldSerializersi.serialize(out,obj,field);82.83.拿默认的 FieldSerializer 举例,还是调用 AbstractHessianOutput 的子类
26、来 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(Illegal
27、AccessException 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.这
28、样 hessian 的序列化架构已经都看完了,同理可以反推出 hessian 的反序列化机制。SerializerFactory 可以根据需要被反序列化的类来获得反序列化工具类来做反序列化操作 Java 代码 1.public Object readObject(AbstractHessianInput in)2.throws IOException 3.Object obj=in.readObject();4.5.String className=getClass().getName();6.7.8.if(obj!=null)9.throw error(className+:unexpect
29、ed object +obj.getCla ss().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.
30、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
31、.else Deserializer reader;25.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.ge
32、tType()&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=rea
33、dType();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).readO bject(this);72.73.return value;74.看见网上还有把 memcached 的序列化实现改成用 hessian 的来实现,目前还没有 做研究,有兴趣的朋友可以实践一下,说得比较多了,大体上的 hessian 的序列化与反序列化的机制就说到这里了,贴 上来的代码不齐全,代码版本是 hessian-3_2-snap-src,感兴趣的可以去 hessian 官网直接下载源码阅读。