精尽 Dubbo 源码分析 —— 序列化(一)之总体实现

1. 概述

在 《Dubbo 开发指南 —— 序列化扩展.》 ,对序列化定义如下:

将对象转成字节流,用于网络传输,以及将字节流转为对象,用于在收到字节流数据后还原成对象。
API 接口,类图如下:

精尽 Dubbo 源码分析 —— 序列化(一)之总体实现_第1张图片

2. 源码实现

2.1 Serialization
/**
 * Serialization. (SPI, Singleton, ThreadSafe)
 *
 * 序列化接口
 */
@SPI("hessian2")
public interface Serialization {

    /**
     * get content type id
     *
     * 获得内容类型编号
     *
     * @return content type id
     */
    byte getContentTypeId();

    /**
     * get content type
     *
     * 获得内容类型名
     *
     * @return content type
     */
    String getContentType();

    /**
     * create serializer
     *
     * 创建 ObjectOutput 对象,序列化输出到 OutputStream
     *
     * @param url URL
     * @param output 输出流
     * @return serializer
     * @throws IOException 当发生 IO 异常时
     */
    @Adaptive
    ObjectOutput serialize(URL url, OutputStream output) throws IOException;

    /**
     * create deserializer
     *
     * 创建 ObjectInput 对象,从 InputStream 反序列化
     *
     * @param url URL
     * @param input 输入流
     * @return deserializer
     * @throws IOException 当发生 IO 异常时
     */
    @Adaptive
    ObjectInput deserialize(URL url, InputStream input) throws IOException;

} 
2.2 DataInput

数据输入接口。方法如下:

boolean readBool() throws IOException;

byte readByte() throws IOException;
short readShort() throws IOException;
int readInt() throws IOException;
long readLong() throws IOException;
float readFloat() throws IOException;
double readDouble() throws IOException;

String readUTF() throws IOException;

byte[] readBytes() throws IOException;

2.2.1 ObjectInput

实现 DataInput 接口,对象输入接口。方法如下:

Object readObject() throws IOException, ClassNotFoundException;
 T readObject(Class cls) throws IOException, ClassNotFoundException;
 T readObject(Class cls, Type type) throws IOException, ClassNotFoundException;

2.3 DataOutput

数据输出接口。方法如下:

void writeBool(boolean v) throws IOException;
    
void writeByte(byte v) throws IOException;
void writeShort(short v) throws IOException;
void writeInt(int v) throws IOException;
void writeLong(long v) throws IOException;
void writeFloat(float v) throws IOException;
void writeDouble(double v) throws IOException;

void writeUTF(String v) throws IOException;

void writeBytes(byte[] v) throws IOException;
void writeBytes(byte[] v, int off, int len) throws IOException;

// Flush buffer.
void flushBuffer() throws IOException;
2.3.1 ObjectOutput

实现 DataOutput 接口,对象输出接口。方法如下:

void writeObject(Object obj) throws IOException;

2.4 Cleanable

清理接口。方法如下:

void cleanup();

2.5 Optimizer 相关

2.5.1 SerializationOptimizer

序列化优化器接口。方法如下:

public interface SerializationOptimizer {

    /**
     * @return 需要使用优化的类的集合
     */
    Collection getSerializableClasses();

}
2.5.2 SerializableClassRegistry

序列化优化类的注册表。代码如下:

public abstract class SerializableClassRegistry {

    private static final Set registrations = new LinkedHashSet();

    /**
     * only supposed to be called at startup time
     */
    public static void registerClass(Class clazz) {
        registrations.add(clazz);
    }

    public static Set getRegisteredClasses() {
        return registrations;
    }

}
2.5.3 初始化序列化优化器

在 DubboProtocol#optimizeSerialization() 方法中,初始化序列化优化器。代码如下:

/**
 * 已初始化的 SerializationOptimizer 实现类名的集合
 */
private final Set optimizers = new ConcurrentHashSet();

private void optimizeSerialization(URL url) throws RpcException {
    // 获得 `"optimizer"` 配置项
    String className = url.getParameter(Constants.OPTIMIZER_KEY, "");
    if (StringUtils.isEmpty(className) || optimizers.contains(className)) { // 已注册
        return;
    }

    logger.info("Optimizing the serialization process for Kryo, FST, etc...");

    try {
        // 加载 SerializationOptimizer 实现类
        Class clazz = Thread.currentThread().getContextClassLoader().loadClass(className);
        if (!SerializationOptimizer.class.isAssignableFrom(clazz)) {
            throw new RpcException("The serialization optimizer " + className + " isn't an instance of " + SerializationOptimizer.class.getName());
        }

        // 创建 SerializationOptimizer 对象
        SerializationOptimizer optimizer = (SerializationOptimizer) clazz.newInstance();
        if (optimizer.getSerializableClasses() == null) {
            return;
        }

        // 注册到 SerializableClassRegistry 中
        for (Class c : optimizer.getSerializableClasses()) {
            SerializableClassRegistry.registerClass(c);
        }

        // 添加到 optimizers 中
        optimizers.add(className);
    } catch (ClassNotFoundException e) {
        throw new RpcException("Cannot find the serialization optimizer class: " + className, e);
    } catch (InstantiationException e) {
        throw new RpcException("Cannot instantiate the serialization optimizer class: " + className, e);
    } catch (IllegalAccessException e) {
        throw new RpcException("Cannot instantiate the serialization optimizer class: " + className, e);
    }
}

你可能感兴趣的:(dubbo源码解析)