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

84人阅读 评论(0) 收藏 举报
分类:

    在数据传输和转换过程中都需要对接口数据进行序列化和反序列化操作,接下来我们看看Dubbo目前都提供了哪些序列化和反序列化实现方式。

    将对象转成字节流,用于网络传输,以及将字节流转为对象,用于在收到字节流数据后还原成对象。

    目前Dubbo提供并实现如下接口来完成数据序列化和反序列操作。

  • com.alibaba.dubbo.common.serialize.Serialization
  • com.alibaba.dubbo.common.serialize.ObjectInput
  • com.alibaba.dubbo.common.serialize.ObjectOutput

    实现类如下:


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

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

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

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

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

@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
     *
     * @param url
     * @param output
     * @return serializer
     * @throws IOException
     */
    @Adaptive
    ObjectOutput serialize(URL url, OutputStream output) throws IOException;

    /**
     * create deserializer
     *
     * @param url
     * @param input
     * @return deserializer
     * @throws IOException
     */
    @Adaptive
    ObjectInput deserialize(URL url, InputStream input) throws IOException;

}

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

public class FastJsonSerialization implements Serialization {

    public byte getContentTypeId() {
        return 6;
    }

    public String getContentType() {
        return "text/json";
    }
	//将数据流进行序列化操作
    public ObjectOutput serialize(URL url, OutputStream output) throws IOException {
        return new FastJsonObjectOutput(output);
    }
	//将数据流进行反序列化操作
    public ObjectInput deserialize(URL url, InputStream input) throws IOException {
        return new FastJsonObjectInput(input);
    }

}

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

ObjectInput接口:

public interface ObjectInput extends DataInput {

    /**
     * read object.
     *
     * @return object.
     */
    Object readObject() throws IOException, ClassNotFoundException;

    /**
     * read object.
     *
     * @param cls object type.
     * @return object.
     */
    <T> T readObject(Class<T> cls) throws IOException, ClassNotFoundException;

    /**
     * read object.
     *
     * @param cls object type.
     * @return object.
     */
    <T> T readObject(Class<T> cls, Type type) throws IOException, ClassNotFoundException;

}

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

public class FastJsonObjectInput implements ObjectInput {

    private final BufferedReader reader;

    public FastJsonObjectInput(InputStream in) {
        this(new InputStreamReader(in));
    }

    public FastJsonObjectInput(Reader reader) {
        this.reader = new BufferedReader(reader);
    }

    public boolean readBool() throws IOException {
        try {
            return readObject(boolean.class);
        } catch (ClassNotFoundException e) {
            throw new IOException(e.getMessage());
        }
    }

    public byte readByte() throws IOException {
        try {
            return readObject(byte.class);
        } catch (ClassNotFoundException e) {
            throw new IOException(e.getMessage());
        }
    }

    public short readShort() throws IOException {
        try {
            return readObject(short.class);
        } catch (ClassNotFoundException e) {
            throw new IOException(e.getMessage());
        }
    }

    public int readInt() throws IOException {
        try {
            return readObject(int.class);
        } catch (ClassNotFoundException e) {
            throw new IOException(e.getMessage());
        }
    }

    public long readLong() throws IOException {
        try {
            return readObject(long.class);
        } catch (ClassNotFoundException e) {
            throw new IOException(e.getMessage());
        }
    }

    public float readFloat() throws IOException {
        try {
            return readObject(float.class);
        } catch (ClassNotFoundException e) {
            throw new IOException(e.getMessage());
        }
    }

    public double readDouble() throws IOException {
        try {
            return readObject(double.class);
        } catch (ClassNotFoundException e) {
            throw new IOException(e.getMessage());
        }
    }

    public String readUTF() throws IOException {
        try {
            return readObject(String.class);
        } catch (ClassNotFoundException e) {
            throw new IOException(e.getMessage());
        }
    }

    public byte[] readBytes() throws IOException {
        return readLine().getBytes();
    }

    public Object readObject() throws IOException, ClassNotFoundException {
        String json = readLine();
        return JSON.parse(json);
    }

    public <T> T readObject(Class<T> cls) throws IOException, ClassNotFoundException {
        String json = readLine();
        return JSON.parseObject(json, cls);
    }

    @SuppressWarnings("unchecked")
    public <T> T readObject(Class<T> cls, Type type) throws IOException, ClassNotFoundException {
        Object value = readObject(cls);
        return (T) PojoUtils.realize(value, cls, type);
    }

    private String readLine() throws IOException, EOFException {
        String line = reader.readLine();
        if (line == null || line.trim().length() == 0) throw new EOFException();
        return line;
    }

}

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

public interface ObjectOutput extends DataOutput {

    /**
     * write object.
     *
     * @param obj object.
     */
    void writeObject(Object obj) throws IOException;

}

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

public class FastJsonObjectOutput implements ObjectOutput {

    private final PrintWriter writer;

    public FastJsonObjectOutput(OutputStream out) {
        this(new OutputStreamWriter(out));
    }

    public FastJsonObjectOutput(Writer writer) {
        this.writer = new PrintWriter(writer);
    }

    public void writeBool(boolean v) throws IOException {
        writeObject(v);
    }

    public void writeByte(byte v) throws IOException {
        writeObject(v);
    }

    public void writeShort(short v) throws IOException {
        writeObject(v);
    }

    public void writeInt(int v) throws IOException {
        writeObject(v);
    }

    public void writeLong(long v) throws IOException {
        writeObject(v);
    }

    public void writeFloat(float v) throws IOException {
        writeObject(v);
    }

    public void writeDouble(double v) throws IOException {
        writeObject(v);
    }

    public void writeUTF(String v) throws IOException {
        writeObject(v);
    }

    public void writeBytes(byte[] b) throws IOException {
        writer.println(new String(b));
    }

    public void writeBytes(byte[] b, int off, int len) throws IOException {
        writer.println(new String(b, off, len));
    }

    public void writeObject(Object obj) throws IOException {
        SerializeWriter out = new SerializeWriter();
        JSONSerializer serializer = new JSONSerializer(out);
        serializer.config(SerializerFeature.WriteEnumUsingToString, true);
        serializer.write(obj);
        out.writeTo(writer);
        out.close(); // for reuse SerializeWriter buf
        writer.println();
        writer.flush();
    }

    public void flushBuffer() throws IOException {
        writer.flush();
    }

}

查看评论

Web Application 開 發 利 器 - WebSnap(六)

Web Application 開 發 利 器 - WebSnap!第 六 章 、 執 行 者 : TAdapterDispatcher 及 AdapterAction  6-1 Action 的 運...
  • rh
  • rh
  • 2001-12-09 15:33:00
  • 1035

开发过程中dubbo 实体序列化问题

首先想到的是java为什么要序列化?网上看到的一篇文章如下。 http://blog.csdn.net/wangloveall/article/details/7992448/ 开发过程中的问题...
  • lovesummerforever
  • lovesummerforever
  • 2016-09-06 17:05:12
  • 9514

dubbo序列化的一点注意

 dubbo序列化的一点注意          最近工作中遇见了一个小问题,在此记录一下,大致是这样的,有一父类,有一个属性traceId,主要是记录日志号,这样可以把所有日志串起...
  • yangxs_cn
  • yangxs_cn
  • 2016-10-18 10:04:42
  • 7570

dubbo的反序列化问题Decode argument failed

最近在一个dubbo接口的provider端出现了这样的错误信息: [WARN ] 2017-11-1100:03:02,354 --New I/O worker #16--[com.alibaba...
  • lkforce
  • lkforce
  • 2017-11-14 11:46:06
  • 524

dubbo 序列化实例

最近在做CMS中excel数据批量录入数据库这个功能,遇到了dubbo序列化问题。这里做总结。 先说一下java为何需要序列化:  1.Java序列化与反序列化  Java序列化是指...
  • a1165117473
  • a1165117473
  • 2017-09-01 11:18:44
  • 683

Dubbo序列化

在Dubbo RPC中,同时支持多种序列化方式: (1)dubbo序列化,阿里尚不成熟的java序列化实现。 (2)hessian2序列化:hessian是一种跨语言的高效二进制的序列化方式,但这...
  • CHS007chs
  • CHS007chs
  • 2017-08-03 13:42:48
  • 507

dubbo序列化的一点注意

dubbo序列化的一点注意注意 最近工作中遇见了一个小问题,在此记录一下,大致是这样的,有一父类,有一个属性traceId,主要是记录日志号,这样可以把所有日志串起来,利于排查问题...
  • qq_16055765
  • qq_16055765
  • 2018-03-22 14:39:19
  • 26

Dubbo中使用高效的Java序列化(Kryo和FST)

序列化漫谈 dubbo RPC是dubbo体系中最核心的一种高性能、高吞吐量的远程调用方式,我喜欢称之为多路复用的TCP长连接调用,简单的说: 长连接:避免了每次调用新建TCP连接,提...
  • moonpure
  • moonpure
  • 2016-11-15 19:28:09
  • 15635

Dubbo序列化问题排查

h1. 现象 为一个dubbbo接口新增了一个方法:{code} DomainObject testSer(); 实现: @Override public DomainObject te...
  • wanyanxgf
  • wanyanxgf
  • 2011-11-07 19:17:08
  • 10045

java原生序列化和Kryo(dubbo)序列化性能比较

简介 最近几年,各种新的高效序列化方式层出不穷,不断刷新序列化性能的上限,最典型的包括: 专门针对Java语言的:Kryo,FST等等跨语言的:Protostuff,ProtoBuf,Th...
  • wanbf123
  • wanbf123
  • 2017-09-14 20:24:50
  • 467
    个人资料
    专栏达人 持之以恒
    等级:
    访问量: 69万+
    积分: 1万+
    排名: 2158
    Github
    访问:https://github.com/IAMTJW
    博客专栏
    最新评论