Netty序列化解析

state:writing

前言

之前被同事问到Netty里面怎么实现Java对象的编解码,对于这个问题不是很清楚,所以花了点时间看了下Netty里面编解码的源代码,记录在这篇文章中。
Netty提供了ObjectEncoderObjectDecoder这两个类来支持对对象的编码和解码工作。

第一部分:编码(ObjectEncoder)

  1. 用法

  2. 源代码分析
    ObjectEncoder类继承关系如下图所示:
    `ObjectEncoder`
    ObjectEncoder类的实现比较简单,代码如下:

    @Sharable
    public class ObjectEncoder extends MessageToByteEncoder<Serializable> {
        private static final byte[] LENGTH_PLACEHOLDER = new byte[4];
        @Override
        protected void encode(ChannelHandlerContext ctx, Serializable msg, ByteBuf out) throws Exception {
            int startIdx = out.writerIndex(); // 记录被序列化对象的起始的位置
            ByteBufOutputStream bout = new ByteBufOutputStream(out);
            bout.write(LENGTH_PLACEHOLDER);
            ObjectOutputStream oout = new CompactObjectOutputStream(bout);
            // 把msg写入到底层的Bytebuf容器中        
            oout.writeObject(msg);
            oout.flush();
            oout.close();
            int endIdx = out.writerIndex();  
            out.setInt(startIdx, endIdx - startIdx - 4); // 把被序列化对象占用的字节数写入startIndex的位置
        }
    }
    

    从代码里面可以看到,ObjectEncoder底层是使用Java原生的序列化接口ObjectInputStream进行序列化的。关于ObjectInputStream可以参见之前的一篇文章深入学习Java序列化
    但是在写入被序列化的对象之前,ObjectEncoder会先预留四个字节用来记录被序列化对象占用的字节数。

第二部分:解码(ObjectDecoder)

  1. 用法

  2. 源代码分析
    ObjectEncoder类继承关系如下图所示:
    `ObjectEncoder`

2017-05-03 22:0733