02.google protobuf

一、简介

官网:https://developers.google.com/protocol-buffers/  或者  https://developers.google.cn/protocol-buffers

托管gitbub地址:https://github.com/protocolbuffers/protobuf

介绍:是一种语言中立、平台中立、可扩展的机制,用于序列号结构化数据。比如如果用http传输,传输的比如是json或xml,效率低,而使用protobuf可以将数据压缩后传输;如果使用java系列化,则无法实现与非java语言交换数据,而使用protobuf可以实现与其他语言交换数据。

Rpc支持的语言越多,提供的数据类型越少,因为数据类型一定是所有支持语言数据类型的交集。

protobuf支持语言:C++ C# Dart Go Java Python

二、使用

1、搭建protobuf开发环境

        1)下载protobuf编译器

 

protoc开头的才是编译器

      2)解压后放在任意路径,并将bin路径配置到环境变量path下(windows),linux修改对应的环境遍历配置文件

      3)下载针对特定语言的protobuf文件,这里下载JAVA的

这个压缩包其实是特定语言涉及的protocolbuf源码、依赖,如果项目使用gradle或者maven管理的话,此步可以省略

      4)在工程中引入开发protobuf程序依赖包

      Protobuf runtime installation,是从这个链接进来

Maven依赖:

protobuf-java:开发protobuf程序依赖的核心包

protobuf-java-util:开发protobuf辅助类、比如json支持

Gradle依赖:

2、开发protobuf程序

示例来源:https://developers.google.cn/protocol-buffers/docs/javatutorial

2.1定义将要传递的消息格式

1)分析消息中属性

2)编写.proto文件

  1. package:protobuf中的包(.proto文件的起始标记)
  2. java_package:java中的包,如果package与java_package同时有,生成java代码中的包路径则以java_package为准,如果没有java_package,生成java代码中的包路径则以package为准,package是必须的属性用于其他没有包概念的语言区分命名空间用的,java_package是可选的属性(专门用于java语言的)最佳实践:如果IDL是准备给java语言用,则java_package不要省略,因为通常package的值不是按照java中规则设置的(com.mzj.xxx)
  3. java_outer_classname:是用于定义生成的java源码文件最外层的java文件类名(protobuf生成的源码默认只有一个类文件,IDL中定义的message作为这个类的内部类),这个文件包含了所有下面定义的java类,也就是下面定义的java类,都会生成在这个外层类内部,称为这个类的内部类;如果不设置这个选项,默认采用IDL文件名转换驼峰的方式生成。最佳实践:如果IDL是准备给java语言用,则java_outer_classname不要省略
  4. protobuf的IDL主体,是以一个个message(消息)组成,一个message代表一个对象类型
  5. Protobuf的IDL支持类型:bool、int32、float、double、string
  6. 可以自定义类型,如Person类型
  7. 可以自定义类型嵌套,如:PhoneNumber是Person的内部类型
  8. 可以定义枚举类型,例子中enum是枚举类型
  9. 字段名称protobuf推荐使用_分割字母,因为为了适应多语言的要求,而java语言时,会在编译后自动转成驼峰形式
  10. =1,=2,=3:是唯一标识字段的(一个消息内唯一,不能重复)标记1-15用于常用的字段,16以后用于不常用字段(因为15以内的标记,占用字节少,可以减少少许传输大小)。注意不同message中标识也不能重复
  11. 字段类型标记:①required必须的,使用不当可能抛出RuntimeException、IOException,②optional可选的,如果不指定,则采用默认值,设置optional字段默认值方式:如果不指定optional的默认值,则采用系统提供的默认值③repeated可重复的(实际上是java中ArrayList)
  12. 如:repeated string names;表示names是一个集合类型,集合中元素是string类型
  13. 注意:设置字段是required是需要小心的,如果一开始设置成required,以后想要改成optional是不可以的(会产生兼容问题)。最佳实践:不要使用required,而使用optional、repeated,因为required的扩展性、兼容性不强。
  14. proto的IDL不支持继承(protobuf不支持继承)

2.2编译IDL文件(即.proto文件)

编译生成的类文件说明:

  • 最外层:AddressBookProtos.java
  • java文件里针对每一个消息(message)都生成了一个内部class,每一个类内部也都有个Builder类,可以用这个Builder类型创建对应message的实例(构造器设计模式)
  • 消息只有get方法,构造器即有get,也有set方法
  • 消息message:

  • 构造器Builder

  • 由protobuf创建的message类是不可修改的类。
  • 创建消息对象,并设值,是通过创建消息对应的Builder对象并调用Builder对象的setXXX进行设值,最后通过build方法创建message:(一句话概述:通过构造器模式以方法链方式创建message)

  • 消息的标准通用方法

生成的消息类有一些通用方法供编程中调用:

  • 消息的解析与序列化方法

消息对象构造完成或者获取到消息流后,对消息进行序列化与反序列化

不只是只有上面官网给出的这些方法,还有其他方法:

  • 消息不能通过继承进行扩展,如果想扩展,只能通过组合方式
  • protoc生成的java文件永远不要试图修改,因为如果重新生成,修改就没有了

最佳实践:不要修改protoc生成的java文件

  • 实际开发时更多的细节参考protobuf的language guide

https://developers.google.cn/protocol-buffers/docs/proto

完整程序示例:

https://github.com/mazhongjia/nettyssynetty02/tree/master/src/main/java/com/mzj/netty/ssy/_06/protobuf

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值