暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

Java序列化库protostuff介绍

程序员升级之路 2021-08-29
4299


一、什么是protostuff

protostuff是一个开箱即用的序列化库,使用非常简单,相对其它序列化库,protostuff优势在于:

1、使用简单

Protobuf每次要编写接口定义文件,然后还要编译,操作太繁琐;


2、高性能

相对json等文本序列化库,protostuff是二进制的,因此性能比json等方式高;


可以说protostuff在高性能和使用成本上做了很好的取舍。


以下是其相关资料:

github:https://codechina.csdn.net/mirrors/protostuff/protostuff

官方文档:https://protostuff.github.io/docs/protostuff-runtime/


总的来说文档还是比较少的,原理需要自己结合代码看下。 


二、使用

要使用protostuff非常简单,只要在需要序列化的成员上加上Tag注解,并写明顺序就行了,接下来我们看具体怎么使用;



1、加入依赖

    <dependency>
    <groupId>io.protostuff</groupId>
    <artifactId>protostuff-core</artifactId>
    <version>1.4.0</version>
    </dependency>


    <dependency>
    <groupId>io.protostuff</groupId>
    <artifactId>protostuff-runtime</artifactId>
    <version>1.4.0</version>
    </dependency>
    复制


    2、编写Demo

    假设我们要序列化一个Student的类,定义如下:

      public class Student {
      @Tag(1)
      private String name;
      @Tag(2)
      private String studentNo;
      @Tag(3)
      private int age;
      @Tag(4)
      private String schoolName;
      @Tag(5)
      private Address address;


      public Student(){
      this.address= new Address();
      }


      public String getName() {
      return name;
      }


      public void setName(String name) {
      this.name = name;
      }


      public String getStudentNo() {
      return studentNo;
      }


      public void setStudentNo(String studentNo) {
      this.studentNo = studentNo;
      }


      public int getAge() {
      return age;
      }


      public void setAge(int age) {
      this.age = age;
      }


      public String getSchoolName() {
      return schoolName;
      }


      public void setSchoolName(String schoolName) {
      this.schoolName = schoolName;
      }


      public Address getAddress() {
      return address;
      }


      public void setAddress(Address address) {
      this.address = address;
          }


      }
      复制


      Address类定义如下:

        ublic class Address {
        @Tag(1)
        private String province;
        @Tag(2)
        private String city;


        public Address(){


        }


        public String getProvince() {
        return province;
        }


        public void setProvince(String province) {
        this.province = province;
        }


        public String getCity() {
        return city;
        }


        public void setCity(String city) {
        this.city = city;
            }
        }
        复制


        可以看到,我们只需要在类的属性上加个Tag的注解,并写明顺序,注意Tag的值必须从1开始。


        然后就可以编写测试了:

           Student student = new Student();
          student.setName("lance");
          student.setAge(28);
          student.setStudentNo("2011070122");
          student.setSchoolName("BJUT");


          student.setAddress(new Address());
          student.getAddress().setProvince("address");
            student.getAddress().setCity("hunan");
            //序列化
            Schema schema = RuntimeSchema.getSchema(student.getClass());
            byte[] bytes = ProtobufIOUtil.toByteArray(o, schema, LinkedBuffer.allocate());


            Student deSerializerResult = Student.class.newInstance();
            ProtostuffIOUtil.mergeFrom(bytes, deSerializerResult, schema);


          System.out.println("deSerializerResult:" + deSerializerResult.toString());
          }
          复制


          正常的话可以输出Student对象了;


          三、其它

          1、Dubbo中使用

          可以通过设置serialization属性为protostuff;


          2、返回/接收客户端内容为protostuff协议

          在Controller上加上相应的@Consumes和@Produces注解:

          @Consumes({ MediaTypeExt.APPLICATION_PROTOSTUFF_V2})

          @Produces({ MediaTypeExt.APPLICATION_PROTOSTUFF_V2})


          四、注意事项

          1、Tag值在父类和子类中唯一;

          如果父类已经定义了Tag(11),则子类则不能用11这个Tag了;


          2、成员为对象的,Tag号可以从1开始

          像上面的Student有个Address成员,它的成员的Tag号从1开始,这个不会造成数据覆盖;



          多机房RPC调用实践

          聊聊DDD的分层架构

          一文讲明白内存重排序

          文章转载自程序员升级之路,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

          评论