目录

1 serialize层概述

2 序列化的简单例子

2.1 项目截图

 2.2 三个类的源码

2.2.1 ABC是实体类

2.2.2 TestSeriarsWrite把ABC对象序列化到文件中

2.2.3 TestSeriarsRead从文件中读取ABC对象

2.2.4 运行结果

 3 展示一个通过URL属性动态切换序列化实现类的例子

3.1 原理分析

 3.2 对象到文件的实现类

 3.3 dubbo支持的序列化实现

 4 总结


1 serialize层概述

dubbo官方架构图:框架设计 | Apache Dubbo

dubbo registry属性 dubbo serialization_序列化

  • serialize 数据序列化层:可复用的一些工具,扩展接口为 SerializationObjectInputObjectOutputThreadPool

Serialize层实现两个功能:

        1)把对象序列化成二进制数据,如:保存到文件中。

        2)根据二进制数据生成java的对象,如:从磁盘文件中读取对象。

有两个场景需要把JVM中的对象序列化:

        1)想把一个对象,发送给另外一个应用。

        2)想把一个对象,存储到文件中。

2 序列化的简单例子

2.1 项目截图

ABC是实体类,TestSeriarsWrite把ABC对象序列化到文件中,TestSeriarsRead从文件中读取ABC对象。

dubbo registry属性 dubbo serialization_dubbo_02

 2.2 三个类的源码

2.2.1 ABC是实体类

package org.example.dubbo.serialize;

import java.io.Serializable;

/** 实体类*/
public class ABC implements Serializable {
    private String a;
    private Integer b;
    private int c;
    public String getA() {
        return a;
    }
    public void setA(String a) {
        this.a = a;
    }
    public Integer getB() {
        return b;
    }
    public void setB(Integer b) {
        this.b = b;
    }
    public int getC() {
        return c;
    }
    public void setC(int c) {
        this.c = c;
    }
    @Override
    public String toString() {
        return "ABC{" +
                "a='" + a + '\'' +
                ", b=" + b +
                ", c=" + c +
                '}';
    }
}

2.2.2 TestSeriarsWrite把ABC对象序列化到文件中

文件的位置需要修改成自己机器对应的位置。

Hessian2Serialization这个实现可以自己替换成dubbo支持的其他序列化类,如ProtostuffSerialization。

objectOutput.flushBuffer() 方法不调用,有的序列化类不输出,及生产的文件没有内容。

package org.example.dubbo.serialize;
import org.apache.dubbo.common.serialize.ObjectOutput;
import org.apache.dubbo.common.serialize.Serialization;
import org.apache.dubbo.common.serialize.hessian2.Hessian2Serialization;

import java.io.FileOutputStream;
import java.io.IOException;

/** 对象序列化到文件中  */
public class TestSeriarsWrite {
    public static void main(String[] args) throws IOException {
        FileOutputStream fileOutputStream = new FileOutputStream("E:\\a\\abc.txt");
        Serialization serialization = new Hessian2Serialization();

        ABC abc = new ABC();
        abc.setA("aaa");
        abc.setB(10);
        abc.setC(20);

        ObjectOutput objectOutput = serialization.serialize(null, fileOutputStream);
        objectOutput.writeObject(abc);
        objectOutput.flushBuffer();
    }
}

2.2.3 TestSeriarsRead从文件中读取ABC对象

package org.example.dubbo.serialize;
import org.apache.dubbo.common.serialize.ObjectInput;
import org.apache.dubbo.common.serialize.Serialization;
import org.apache.dubbo.common.serialize.hessian2.Hessian2Serialization;

import java.io.FileInputStream;
import java.io.IOException;

/** 从文件中加载对象 */
public class TestSeriarsRead {
    public static void main(String[] args) throws IOException, ClassNotFoundException {
        Serialization serialization = new Hessian2Serialization();
        FileInputStream fileInputStream = new FileInputStream("E:\\a\\abc.txt");
        ObjectInput deserialize = serialization.deserialize(null, fileInputStream);
        ABC abc = deserialize.readObject(ABC.class);
        System.out.println(abc);
    }
}

2.2.4 运行结果

先运行TestSeriarsWrite类,再运行TestSeriarsRead类,会发现可以从文件中获取到该ABC类的对象。

文件内容:

dubbo registry属性 dubbo serialization_dubbo_03

 TestSeriarsRead类运行的结果:

dubbo registry属性 dubbo serialization_dubbo_04

 3 展示一个通过URL属性动态切换序列化实现类的例子

3.1 原理分析

通过dubbo源码,可以看到Serialization是一个自适应扩展点,这样就能实现通过URL属性切换扩展(即实现类)的能力。

由于@Adaptive注解没有指定value值,所以url中的参数名字就是接口的名字,如果是驼峰写法,如XxxYyy,则url参数为xxx.yyy。

dubbo registry属性 dubbo serialization_序列化_05

 3.2 对象到文件的实现类

package org.example.dubbo.serialize;
import org.apache.dubbo.common.URL;
import org.apache.dubbo.common.URLBuilder;
import org.apache.dubbo.common.extension.ExtensionLoader;
import org.apache.dubbo.common.serialize.ObjectOutput;
import org.apache.dubbo.common.serialize.Serialization;

import java.io.FileOutputStream;
import java.io.IOException;

/** 对象序列化到文件中  */
public class TestUrlSeriarsWrite {
    public static void main(String[] args) throws IOException {
        String serializtionName = "hessian2";
        if (args.length > 0) {
            serializtionName = args[0];
        }
        System.out.println("序列化实现类为:" + serializtionName);
        FileOutputStream fileOutputStream = new FileOutputStream("E:\\a\\abc.txt");

        //获取自适应扩展
        Serialization adaptiveExtension = ExtensionLoader.getExtensionLoader(Serialization.class)
                .getAdaptiveExtension();

        ABC abc = new ABC();
        abc.setA("aaa");
        abc.setB(10);
        abc.setC(20);

        //创建Url
        URLBuilder urlBuilder = new URLBuilder();
        urlBuilder.addParameter("serialization", serializtionName);
        URL url = urlBuilder.build();

        //通过URL中的serialization参数,选择对应的实现类
        ObjectOutput objectOutput = adaptiveExtension.serialize(url, fileOutputStream);
        objectOutput.writeObject(abc);
        objectOutput.flushBuffer();
    }
}

通过idea的运行TestUrlSeriarsWrite类,并指定扩展的实现类名称。目前配置的fastjson。

dubbo registry属性 dubbo serialization_dubbo registry属性_06

 运行程序后,可以看到对应的文件:E:\a\abc.txt。已经是json格式了。

dubbo registry属性 dubbo serialization_dubbo_07

 3.3 dubbo支持的序列化实现

可以参考dubbo jar包的文件:org.apache.dubbo.common.serialize.Serialization。

等号前面的是扩展的名称,等号右面的是具体的java实现类。

dubbo registry属性 dubbo serialization_apache_08

 4 总结

本文描述了dubbo serialize层API的简单使用。 原理请自行网上搜索(网上描述的都比较详细了,就不在copy一份了。)。

下一篇将举例transport层的使用。