[TOC]
1.dubbo hessian2 序列化协议
Dubbo 默认的hessian2序列化协议内部嵌入了Hessian-lite源码,其中Hessian-lite最初是阿里巴巴dubbo嵌入官方hessian的版本,后来从dubbo分离出来。dubbo源码中的dubbo-serialization模块是dubbo支持的序列化方式,而hessian2序列化方式中org.apache.dubbo.common.serialize.hessian2包内有以下四个类:
- Hessian2ObjectInput:该类实现了ObjectInput(继承了DataInput接口)接口,其内部拥有Hessian2Input类属性(Hessian-lite jar包内),所有的读对象操作都委托给Hessian2Input来进行。
- Hessian2ObjectOutput:该类实现了ObjectOutput(继承了DataOutput接口)接口,其内部拥有Hessian2Output类属性(Hessian-lite jar包内),所有的写对象操作都委托给Hessian2Output来进行。
- Hessian2Serialization:该类实现了Serialization接口,并实现了其中的方法 ,其中Serialization也是使用dubbo 自适应扩展方式来获取扩展实例的。
- Hessian2SerializerFactory:序列化工厂,继承了Hessian-lite包中的SerializerFactory。
2. dubbo hessian2 序列化协议在dubbo中的应用
2.1 调用链路分析
在消费端调用服务方法时,会触发以下调用链路:DubboInvoker 的 doInvoke 方法 —> NettyCodecAdapter 中内部类 InternalEncoder 的 encode 方法—> DubboCodec 类的 encode 方法 —> ExchangeCodec 的 encode 方法 —> Hessian2ObjectOutput 的 writeObject 的方法。
2.2 序列化原理分析
这里看Hessian2ObjectOutput 的 writeObject 的方法,实际上调用的是Hessian-lite jar包内的 Hessian2Output 的 writeObject 方法:
public void writeObject(Object object) throws IOException {
//......
Serializer serializer;
// 获取序列化器,搜索符合条件的 Serializer, 默认 JavaSerializer
serializer = findSerializerFactory().getSerializer(object.getClass());
serializer.writeObject(object, this);
}
public class SerializerFactory extends AbstractSerializerFactory {
//......
public Serializer getSerializer(Class cl) throws HessianProtocolException {
Serializer serializer;
// 先尝试从基本的序列化器中查找,静态加载
serializer = (Serializer) _staticSerializerMap.get(cl);
if (serializer != null) {
return serializer;
}
// 缓存中查找
if (_cachedSerializerMap != null) {
serializer = (Serializer) _cachedSerializerMap.get(cl);
if (serializer != null) {
return serializer;
}
}
// 初始化多个工厂类
for (int i = 0; serializer == null && _factories != null && i < _factories.size(); i++){
AbstractSerializerFactory factory;
factory = (AbstractSerializerFactory) _factories.get(i);
serializer = factory.getSerializer(cl);
}
if (serializer != null) {
} else if (isZoneId(cl))
serializer = ZoneIdSerializer.getInstance();
else if (isEnumSet(cl))
serializer = EnumSetSerializer.getInstance();
else if (JavaSerializer.getWriteReplace(cl) != null)
serializer = new JavaSerializer(cl, _loader);
else if (HessianRemoteObject.class.isAssignableFrom(cl))
serializer = new RemoteSerializer();
else if (Map.class.isAssignableFrom(cl)) {
if (_mapSerializer == null)
_mapSerializer = new MapSerializer();
serializer = _mapSerializer;
} else if (Collection.class.isAssignableFrom(cl)) {
if (_collectionSerializer == null) {
_collectionSerializer = new CollectionSerializer();
}
serializer = _collectionSerializer;
} else if (cl.isArray()) {
serializer = new ArraySerializer();
} else if (Throwable.class.isAssignableFrom(cl)) {
serializer = new ThrowableSerializer(cl, getClassLoader());
} else if (InputStream.class.isAssignableFrom(cl)) {
serializer = new InputStreamSerializer();
} else if (Iterator.class.isAssignableFrom(cl)) {
serializer = IteratorSerializer.create();
} else if (Enumeration.class.isAssignableFrom(cl)) {
serializer = EnumerationSerializer.create();
} else if (Calendar.class.isAssignableFrom(cl)) {
serializer = CalendarSerializer.create();
} else if (Locale.class.isAssignableFrom(cl)) {
serializer = LocaleSerializer.create();
} else if (Enum.class.isAssignableFrom(cl)) {
serializer = new EnumSerializer(cl);
}
if (serializer == null) {
serializer = getDefaultSerializer(cl);
}
if (_cachedSerializerMap == null) {
_cachedSerializerMap = new ConcurrentHashMap(8);
}
_cachedSerializerMap.put(cl, serializer);
return serializer;
}
}
这里看一下 JavaSerializer 的 writeObject 方法,源码如下:
@Override
public void writeObject(Object obj, AbstractHessianOutput out) throws IOException {
// 判断obj对象是否已经被写入引用关系,若已经写入,该方法返回
if (out.addRef(obj)) {
return;
}
Class cl = obj.getClass();
// try catch 省略
if (_writeReplace != null) {
Object repl;
if (_writeReplaceFactory != null)
repl = _writeReplace.invoke(_writeReplaceFactory, obj);
else
repl = _writeReplace.invoke(obj);
out.removeRef(obj);
out.writeObject(repl);
out.replaceRef(repl, obj);
return;
}
// 写类名
int ref = out.writeObjectBegin(cl.getName());
if (ref < -1) {
writeObject10(obj, out);
} else {
if (ref == -1) {
writeDefinition20(out);
out.writeObjectBegin(cl.getName());
}
writeInstance(obj, out);
}
}
public void writeInstance(Object obj, AbstractHessianOutput out) throws IOException {
for (int i = 0; i < _fields.length; i++) {
Field field = _fields[i];
// 依次写字段信息,BooleanFieldSerializer、IntFieldSerializer、LongFieldSerializer、DoubleFieldSerializer、StringFieldSerializer、DateFieldSerializer都是静态内部类FieldSerializer的子类,根据不同的属性走不同类型的Serializer
_fieldSerializers[i].serialize(out, obj, field);
}
}
上面若以 StringFieldSerializer.serialize 为例,最终会交给Hessian2Output writeString来处理写入(把值转换为二进制)
3. dubbo jdk序列化协议
dubbo中也提供了jdk原生序列化方式,序列化时委托给java中的ObjectInputStream和ObjectOutputStream进行对象的生成和解码(序列化对象的字段的元数据)
网友评论