Dubbo源码学习--接口数据序列化Serialization

£神魔★判官ぃ 2022-05-27 08:28 468阅读 0赞
  1. 在数据传输和转换过程中都需要对接口数据进行序列化和反序列化操作,接下来我们看看Dubbo目前都提供了哪些序列化和反序列化实现方式。
  2. 将对象转成字节流,用于网络传输,以及将字节流转为对象,用于在收到字节流数据后还原成对象。
  3. 目前Dubbo提供并实现如下接口来完成数据序列化和反序列操作。
  • com.alibaba.dubbo.common.serialize.Serialization
  • com.alibaba.dubbo.common.serialize.ObjectInput
  • com.alibaba.dubbo.common.serialize.ObjectOutput

    实现类如下:

70

在Dubbo项目开发中可以通过如下配置来选择序列化和反序列化方式:

  1. <!-- 协议的序列化方式 -->
  2. <dubbo:protocol serialization="fastjson" />
  3. <!-- 缺省值设置,当<dubbo:protocol>没有配置serialization时,使用此配置 -->
  4. <dubbo:provider serialization="java" />

接下来我们通过分析几个序列化和反序列化实现类,看看Dubbo是如何实现的。

Serialization接口默认会选择hessian2作为序列化和反序列化的实现接口

Serialization中提供了serialize和deserialize接口对数据进行序列化和反序列化操作。

  1. @SPI("hessian2")
  2. public interface Serialization {
  3. /**
  4. * get content type id
  5. *
  6. * @return content type id
  7. */
  8. byte getContentTypeId();
  9. /**
  10. * get content type
  11. *
  12. * @return content type
  13. */
  14. String getContentType();
  15. /**
  16. * create serializer
  17. *
  18. * @param url
  19. * @param output
  20. * @return serializer
  21. * @throws IOException
  22. */
  23. @Adaptive
  24. ObjectOutput serialize(URL url, OutputStream output) throws IOException;
  25. /**
  26. * create deserializer
  27. *
  28. * @param url
  29. * @param input
  30. * @return deserializer
  31. * @throws IOException
  32. */
  33. @Adaptive
  34. ObjectInput deserialize(URL url, InputStream input) throws IOException;
  35. }

接下来我们分析常见的FastJson序列化方式:

  1. public class FastJsonSerialization implements Serialization {
  2. public byte getContentTypeId() {
  3. return 6;
  4. }
  5. public String getContentType() {
  6. return "text/json";
  7. }
  8. //将数据流进行序列化操作
  9. public ObjectOutput serialize(URL url, OutputStream output) throws IOException {
  10. return new FastJsonObjectOutput(output);
  11. }
  12. //将数据流进行反序列化操作
  13. public ObjectInput deserialize(URL url, InputStream input) throws IOException {
  14. return new FastJsonObjectInput(input);
  15. }
  16. }

在序列化和反序列中Dubbo提供对象输出和输入两个接口ObjectInput和ObjectOutput用于真正实现数据序列化和反序列化操作。

ObjectInput接口:

  1. public interface ObjectInput extends DataInput {
  2. /**
  3. * read object.
  4. *
  5. * @return object.
  6. */
  7. Object readObject() throws IOException, ClassNotFoundException;
  8. /**
  9. * read object.
  10. *
  11. * @param cls object type.
  12. * @return object.
  13. */
  14. <T> T readObject(Class<T> cls) throws IOException, ClassNotFoundException;
  15. /**
  16. * read object.
  17. *
  18. * @param cls object type.
  19. * @return object.
  20. */
  21. <T> T readObject(Class<T> cls, Type type) throws IOException, ClassNotFoundException;
  22. }

简单看一下FastJsonObjectInput的实现就是利用FastJson的接口实现数据反序列化操作。

  1. public class FastJsonObjectInput implements ObjectInput {
  2. private final BufferedReader reader;
  3. public FastJsonObjectInput(InputStream in) {
  4. this(new InputStreamReader(in));
  5. }
  6. public FastJsonObjectInput(Reader reader) {
  7. this.reader = new BufferedReader(reader);
  8. }
  9. public boolean readBool() throws IOException {
  10. try {
  11. return readObject(boolean.class);
  12. } catch (ClassNotFoundException e) {
  13. throw new IOException(e.getMessage());
  14. }
  15. }
  16. public byte readByte() throws IOException {
  17. try {
  18. return readObject(byte.class);
  19. } catch (ClassNotFoundException e) {
  20. throw new IOException(e.getMessage());
  21. }
  22. }
  23. public short readShort() throws IOException {
  24. try {
  25. return readObject(short.class);
  26. } catch (ClassNotFoundException e) {
  27. throw new IOException(e.getMessage());
  28. }
  29. }
  30. public int readInt() throws IOException {
  31. try {
  32. return readObject(int.class);
  33. } catch (ClassNotFoundException e) {
  34. throw new IOException(e.getMessage());
  35. }
  36. }
  37. public long readLong() throws IOException {
  38. try {
  39. return readObject(long.class);
  40. } catch (ClassNotFoundException e) {
  41. throw new IOException(e.getMessage());
  42. }
  43. }
  44. public float readFloat() throws IOException {
  45. try {
  46. return readObject(float.class);
  47. } catch (ClassNotFoundException e) {
  48. throw new IOException(e.getMessage());
  49. }
  50. }
  51. public double readDouble() throws IOException {
  52. try {
  53. return readObject(double.class);
  54. } catch (ClassNotFoundException e) {
  55. throw new IOException(e.getMessage());
  56. }
  57. }
  58. public String readUTF() throws IOException {
  59. try {
  60. return readObject(String.class);
  61. } catch (ClassNotFoundException e) {
  62. throw new IOException(e.getMessage());
  63. }
  64. }
  65. public byte[] readBytes() throws IOException {
  66. return readLine().getBytes();
  67. }
  68. public Object readObject() throws IOException, ClassNotFoundException {
  69. String json = readLine();
  70. return JSON.parse(json);
  71. }
  72. public <T> T readObject(Class<T> cls) throws IOException, ClassNotFoundException {
  73. String json = readLine();
  74. return JSON.parseObject(json, cls);
  75. }
  76. @SuppressWarnings("unchecked")
  77. public <T> T readObject(Class<T> cls, Type type) throws IOException, ClassNotFoundException {
  78. Object value = readObject(cls);
  79. return (T) PojoUtils.realize(value, cls, type);
  80. }
  81. private String readLine() throws IOException, EOFException {
  82. String line = reader.readLine();
  83. if (line == null || line.trim().length() == 0) throw new EOFException();
  84. return line;
  85. }
  86. }

ObjectOutPut接口,完成数据序列化输出操作

  1. public interface ObjectOutput extends DataOutput {
  2. /**
  3. * write object.
  4. *
  5. * @param obj object.
  6. */
  7. void writeObject(Object obj) throws IOException;
  8. }

实现类FastJsonObjectOutput简单来说就是使用fastjson接口实现数据序列化并输出操作。

  1. public class FastJsonObjectOutput implements ObjectOutput {
  2. private final PrintWriter writer;
  3. public FastJsonObjectOutput(OutputStream out) {
  4. this(new OutputStreamWriter(out));
  5. }
  6. public FastJsonObjectOutput(Writer writer) {
  7. this.writer = new PrintWriter(writer);
  8. }
  9. public void writeBool(boolean v) throws IOException {
  10. writeObject(v);
  11. }
  12. public void writeByte(byte v) throws IOException {
  13. writeObject(v);
  14. }
  15. public void writeShort(short v) throws IOException {
  16. writeObject(v);
  17. }
  18. public void writeInt(int v) throws IOException {
  19. writeObject(v);
  20. }
  21. public void writeLong(long v) throws IOException {
  22. writeObject(v);
  23. }
  24. public void writeFloat(float v) throws IOException {
  25. writeObject(v);
  26. }
  27. public void writeDouble(double v) throws IOException {
  28. writeObject(v);
  29. }
  30. public void writeUTF(String v) throws IOException {
  31. writeObject(v);
  32. }
  33. public void writeBytes(byte[] b) throws IOException {
  34. writer.println(new String(b));
  35. }
  36. public void writeBytes(byte[] b, int off, int len) throws IOException {
  37. writer.println(new String(b, off, len));
  38. }
  39. public void writeObject(Object obj) throws IOException {
  40. SerializeWriter out = new SerializeWriter();
  41. JSONSerializer serializer = new JSONSerializer(out);
  42. serializer.config(SerializerFeature.WriteEnumUsingToString, true);
  43. serializer.write(obj);
  44. out.writeTo(writer);
  45. out.close(); // for reuse SerializeWriter buf
  46. writer.println();
  47. writer.flush();
  48. }
  49. public void flushBuffer() throws IOException {
  50. writer.flush();
  51. }
  52. }

发表评论

表情:
评论列表 (有 0 条评论,468人围观)

还没有评论,来说两句吧...

相关阅读

    相关 序列Serialization

    1、什么是序列化 在面向对象编程中,一种很常见的需求是,需要保存对象,并在下次使用时可以顺利还原该对象。 2、为什么叫序列化 由于保存对象的过程,是把对象保存为一

    相关 java序列机制Serialize接口

    概念        Java 平台允许我们在内存中创建可复用的 Java 对象,但一般情况下,只有当 JVM 处于运行时, 这些对象才可能存在,即,这些对象的生命周期不会