dubbo 序列化是如何封装的
程序员文章站
2022-04-03 22:12:50
...
dubbo 是支持多种序列化方式的,那么它就必须在此基础上做一层封装,来统一序列化层的接口.
现在我们拿 Java 中的序列化来讲解 dubbo 是如何进行封装的.
如果使用 java 序列化,需要做那几步了?
1.实现 java.io.Serializable
2.new ObjectOutputStream,并调用 writeObject 方法写对象
反序列化:
1.new ObjectInputStream
2.调用 readObject 方法读对象.
那么现在 dubbo 需要在此基础上,可以*使用多种序列化方式,该如何做了?
1.是不是需要一个类似 ObjectOutputStream 和 ObjectInputStream 的角色?是的,在 dubbo 中,它们的名字是DataInput 和 DataOutput
2.光有上面的那两个工具没用呀,需要一个统一多种序列化方式的入口,所以还得一个 Serialization.
3.虽然 dubbo 支持多种序列化方式,那么到底支持哪些了?这些是不是得有一个地方存我支持哪些序列化方式了?确实,在 Constants 中.
4.我们需要对对象序列化的支持,而上面的 DataInput 和 DataOutput 只是对某个值的序列化和反序列化,所以在此基础上,我们需要 ObjectInput 和 ObjectOutput.
5.我们在想远一点,就拿 MySQL 来说吧,每次执行 sql 的时候,会有一个优化器,帮你做出选择,怎么支持会快. 那么序列化是不是也可以这么干了?所以就会有一个 SerializationOptimizer.
6.SerializationOptimizer 中返回的列表会注册到 SerializableClassRegistry 中. 按我的理解,应该是对某些类进行优化序列化吧.
下面来分析下具体的序列化是如何做的,上面只是为统一序列化定义的统一接口.
换句话说,如果我们要自己定义一个序列化方式,应该如何做?
1.实现 Serialization
2.实现 ObjectInput & ObjectOutput
具体看下吧:
这个类很简单,算是入口吧.
public class NativeJavaSerialization implements Serialization {
@Override
public byte getContentTypeId() {
return NATIVE_JAVA_SERIALIZATION_ID;
}
@Override
public String getContentType() {
return "x-application/nativejava";
}
@Override
public ObjectOutput serialize(URL url, OutputStream output) throws IOException {
return new NativeJavaObjectOutput(output);
}
@Override
public ObjectInput deserialize(URL url, InputStream input) throws IOException {
return new NativeJavaObjectInput(input);
}
}
我们看下 ObjectInput & ObjectOutput.
我们可以看到 NativeJavaObjectInput 只是对 ObjectInputStream 的简单封装,NativeJavaObjectOutput 只是对 ObjectOutputStream 的简单封装.
我们再看下 JavaSerialization.
JavaObjectInput 是在 NativeJavaObjectInput 之上构建的,区别是 JavaObjectInput 加入了对空值的判断.
接着看下 CompactedJavaSerialization
CompactedJavaSerialization 的使用场景不了解,暂时不管了.
我也看了下 hessian2 的实现,发现和 JDK 中的实现类似,都是对具体实现的封装,例如 hessian2 是对 Hessian2Input 的封装.
现在我们拿 Java 中的序列化来讲解 dubbo 是如何进行封装的.
如果使用 java 序列化,需要做那几步了?
1.实现 java.io.Serializable
2.new ObjectOutputStream,并调用 writeObject 方法写对象
反序列化:
1.new ObjectInputStream
2.调用 readObject 方法读对象.
那么现在 dubbo 需要在此基础上,可以*使用多种序列化方式,该如何做了?
1.是不是需要一个类似 ObjectOutputStream 和 ObjectInputStream 的角色?是的,在 dubbo 中,它们的名字是DataInput 和 DataOutput
2.光有上面的那两个工具没用呀,需要一个统一多种序列化方式的入口,所以还得一个 Serialization.
3.虽然 dubbo 支持多种序列化方式,那么到底支持哪些了?这些是不是得有一个地方存我支持哪些序列化方式了?确实,在 Constants 中.
4.我们需要对对象序列化的支持,而上面的 DataInput 和 DataOutput 只是对某个值的序列化和反序列化,所以在此基础上,我们需要 ObjectInput 和 ObjectOutput.
5.我们在想远一点,就拿 MySQL 来说吧,每次执行 sql 的时候,会有一个优化器,帮你做出选择,怎么支持会快. 那么序列化是不是也可以这么干了?所以就会有一个 SerializationOptimizer.
6.SerializationOptimizer 中返回的列表会注册到 SerializableClassRegistry 中. 按我的理解,应该是对某些类进行优化序列化吧.
下面来分析下具体的序列化是如何做的,上面只是为统一序列化定义的统一接口.
换句话说,如果我们要自己定义一个序列化方式,应该如何做?
1.实现 Serialization
2.实现 ObjectInput & ObjectOutput
具体看下吧:
这个类很简单,算是入口吧.
public class NativeJavaSerialization implements Serialization {
@Override
public byte getContentTypeId() {
return NATIVE_JAVA_SERIALIZATION_ID;
}
@Override
public String getContentType() {
return "x-application/nativejava";
}
@Override
public ObjectOutput serialize(URL url, OutputStream output) throws IOException {
return new NativeJavaObjectOutput(output);
}
@Override
public ObjectInput deserialize(URL url, InputStream input) throws IOException {
return new NativeJavaObjectInput(input);
}
}
我们看下 ObjectInput & ObjectOutput.
我们可以看到 NativeJavaObjectInput 只是对 ObjectInputStream 的简单封装,NativeJavaObjectOutput 只是对 ObjectOutputStream 的简单封装.
我们再看下 JavaSerialization.
JavaObjectInput 是在 NativeJavaObjectInput 之上构建的,区别是 JavaObjectInput 加入了对空值的判断.
接着看下 CompactedJavaSerialization
CompactedJavaSerialization 的使用场景不了解,暂时不管了.
我也看了下 hessian2 的实现,发现和 JDK 中的实现类似,都是对具体实现的封装,例如 hessian2 是对 Hessian2Input 的封装.