Skip to content

序列化问题

Java对象的序列化主要有两个:

  1. 网络传输

    数据在网络中传输是通过字节流形式的,到服务端需要解码。

  2. 对象持久化

Java序列化

Java序列化机制是基于对象的类结构进行的。

当对象需要序列化时,会将对象转换为字节流在网络传输。

反序列化时,就是将字节流转换为对象的过程。Java会将字节流转换为对象重新加载到内存中。

Java的序列化机制是通过实现java.io.Serializable接口来实现的。该接口是一个标记接口,没有任何方法定义。只有实现了Serializable接口的类的对象才能被序列化。

缺点

  1. 序列化性能较低

    java
    The jdk serializable cost time is  : 1343 ms
    -------------------------------------
    The byte array serializable cost time is : 128 ms
  2. 序列化后字节数组过大

    java
    The jdk serializable length is : 128
    The byte array serializable length is : 24
  3. 不支持跨语言,只支持Java,其它语言无法反序列化。

Protocol Buffers

java
 b.group(bossGroup, workerGroup)
                    .channel(NioServerSocketChannel.class)
                    .option(ChannelOption.SO_BACKLOG, 100)
                    .childHandler(new ChannelInitializer<SocketChannel>() {
                        @Override
                        public void initChannel(SocketChannel ch) {
                            /*去除消息长度部分,同时根据这个消息长度读取实际的数据*/
                            ch.pipeline().addLast(new ProtobufVarint32FrameDecoder());
                            //Protobuf进行解码,反序列化
                            ch.pipeline().addLast(new ProtobufDecoder(PersonProto.Person.getDefaultInstance()));
                            ch.pipeline().addLast(new ProtoBufServerHandler());
                        }
                    });
java
            b.group(group)
                    .channel(NioSocketChannel.class)
                    .option(ChannelOption.TCP_NODELAY, true)
                    .handler(new ChannelInitializer<SocketChannel>() {
                        @Override
                        public void initChannel(SocketChannel ch)
                                throws Exception {
                            /*加一个消息长度,由netty自动计算*/
                            ch.pipeline().addLast(new ProtobufVarint32LengthFieldPrepender());
                            //Protobuf进行编码,负责序列化
                            ch.pipeline().addLast(new ProtobufEncoder());
                            ch.pipeline().addLast(new ProtoBufClientHandler());
                        }
                    });