title: Dubbo源码分析 - FST序列化
categories: RPC
tags:
- Dubbo
comments: false
toc: true
abbrlink: cfaae53
date: 2020-05-05
概述
在 序列化总览 中介绍了 Dubbo 序列化抽象API相关接口,本篇文章将介绍 Dubbo 的 FST 序列化实现。
相关的代码结构如下图所示:

FST 工厂
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49
| public class FstFactory {
private static final FstFactory factory = new FstFactory();
private final FSTConfiguration conf = FSTConfiguration.createDefaultConfiguration();
public static FstFactory getDefaultFactory() { return factory; }
public FstFactory() { for (Class clazz : SerializableClassRegistry.getRegisteredClasses()) { conf.registerClass(clazz); } }
public FSTObjectOutput getObjectOutput(OutputStream outputStream) { return conf.getObjectOutput(outputStream); }
public FSTObjectInput getObjectInput(InputStream inputStream) { return conf.getObjectInput(inputStream); } }
|
值得注意的是,FST 工厂的构造方法中会将 SerializableClassRegistry 注册表中的待序列化优化类,注册到 FSTConfiguration 中。
FstSerialization
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
| public class FstSerialization implements Serialization {
@Override public byte getContentTypeId() { return 9; }
@Override public String getContentType() { return "x-application/fst"; }
@Override public ObjectOutput serialize(URL url, OutputStream out) throws IOException { return new FstObjectOutput(out); }
@Override public ObjectInput deserialize(URL url, InputStream is) throws IOException { return new FstObjectInput(is); } }
|
实现 Serialization 接口,FST 序列化实现类,将序列化任务交给 FstObjectOutput 对象完成,将反序列化任务交给 FstObjectInput 对象完成。
FstObjectOutput
FstObjectOutput 实现序列化抽象API模块的 ObjectOutput 接口。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81
| public class FstObjectOutput implements ObjectOutput {
private FSTObjectOutput output;
public FstObjectOutput(OutputStream outputStream) { output = FstFactory.getDefaultFactory().getObjectOutput(outputStream); }
@Override public void writeBool(boolean v) throws IOException { output.writeBoolean(v); }
@Override public void writeByte(byte v) throws IOException { output.writeByte(v); }
@Override public void writeShort(short v) throws IOException { output.writeShort(v); }
@Override public void writeInt(int v) throws IOException { output.writeInt(v); }
@Override public void writeLong(long v) throws IOException { output.writeLong(v); }
@Override public void writeFloat(float v) throws IOException { output.writeFloat(v); }
@Override public void writeDouble(double v) throws IOException { output.writeDouble(v); }
@Override public void writeBytes(byte[] v) throws IOException { if (v == null) { output.writeInt(-1); } else { writeBytes(v, 0, v.length); } }
@Override public void writeBytes(byte[] v, int off, int len) throws IOException { if (v == null) { output.writeInt(-1); } else { output.writeInt(len); output.write(v, off, len); } }
@Override public void writeUTF(String v) throws IOException { output.writeUTF(v); }
@Override public void writeObject(Object v) throws IOException { output.writeObject(v); }
@Override public void flushBuffer() throws IOException { output.flush(); } }
|
FstObjectOutput 中的序列化方法直接委托给 FSTObjectOutput 中对应的方法。
FstObjectInput 实现序列化抽象API模块的 ObjectInput 接口。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91
| public class FstObjectInput implements ObjectInput {
private FSTObjectInput input;
public FstObjectInput(InputStream inputStream) { input = FstFactory.getDefaultFactory().getObjectInput(inputStream); }
@Override public boolean readBool() throws IOException { return input.readBoolean(); }
@Override public byte readByte() throws IOException { return input.readByte(); }
@Override public short readShort() throws IOException { return input.readShort(); }
@Override public int readInt() throws IOException { return input.readInt(); }
@Override public long readLong() throws IOException { return input.readLong(); }
@Override public float readFloat() throws IOException { return input.readFloat(); }
@Override public double readDouble() throws IOException { return input.readDouble(); }
@Override public String readUTF() throws IOException { return input.readUTF(); }
@Override public Object readObject() throws IOException, ClassNotFoundException { return input.readObject(); }
@Override @SuppressWarnings("unchecked") public <T> T readObject(Class<T> clazz) throws IOException, ClassNotFoundException { try { return (T) input.readObject(clazz); } catch (Exception e) { throw new IOException(e); } }
@Override @SuppressWarnings("unchecked") public <T> T readObject(Class<T> clazz, Type type) throws IOException, ClassNotFoundException { try { return (T) input.readObject(clazz); } catch (Exception e) { throw new IOException(e); } }
@Override public byte[] readBytes() throws IOException { int len = input.readInt(); if (len < 0) { return null; } else if (len == 0) { return new byte[]{}; } else { byte[] b = new byte[len]; input.readFully(b); return b; } } }
|
每个实现方法,直接委托给 FSTObjectInput 对应的方法。
小结
Dubbo 的 FST 序列化方式特殊点在于可以指定要序列化优化的类,然注册到 FSTConfiguration 配置对象中,用以发挥出 FST 的高性能。其中 Kryo 序列化方式和 FST 类似。其它没有分析到的序列化方式套路都是一样的。Dubbo 的序列化到此结束。