序列化 | ProtoBuf - [简介 & 使用]

§1 基本介绍

基本信息

  • Google Protocol Buffers
  • 序列化技术
  • 通过 Message 的形式管理数据
  • 可以自动生成 java 代码
    支持用 .proto 文件描述 java 类,并通过 protoc.exe 编译器自动生成代码

优点

  • 跨平台、跨语言
  • 高性能、高可靠性

应用

  • rpc 序列化
  • 编解码器
    通常结合 Netty 应用,Netty 自带的编解码器底层是 JDK 的序列化
    • 体积大
    • 性能低
    • 不能跨语言

§2 .proto 文件

单数据类型示例

// 版本
syntax =  "proto3"
// 文件名,类名
option java_outer_className = "EntityPOJO"

// message 体,相当于 AVRO 里的 schema
// 对应 EntityPOJO 的内部类
// 实际的 java bean 类
message Entity{
	// 属性的 proto 类型,属性名,属性序号
	int32 id = 1; 
	string name = 2;
}

类型

  • double:double
  • float:float
  • int32:int
  • int64:long
  • uint32:unsigned int
  • uint64:unsigned long
  • sint32:int
  • string:String
  • bytes:ByteString

编译
用于生成 EntityPOJO.java (按上面示例中 java_outer_className)

protoc.exe --java_out=. 文件名

混合数据类型示例

// 版本
syntax =  "proto3"
// 快速解析
option optimize_for = SPEED;
// java 包名
option java_package = "com.xx.xx.xx"
// java 文件名,类名
option java_outer_className = "DataInfo"

// 控制用的 message 
message Dispatcher{
	// 数据类型枚举
	// proto 文件中,枚举编号从 0 开始
	enum DataTyPe{
		EntityType = 0;
		DomainType = 1;
	}
	// 属性的 proto 类型(就是上面的枚举),属性名,属性序号
	DataType dataType = 1; 

	// 下面属性不能同时出现,只能出现其中一个
	// 如下例,entity 和 domain 是 message 的第二、第三属性,但二者不共存
	oneof dataBody(
		Entity entity = 2;
		Domain domain = 3;
	)
}

// message 体,相当于 AVRO 里的 schema
// 对应 DataInfo 的内部类
// 实际的 java bean 类
message Entity{
	// 属性的 proto 类型,属性名,属性序号
	int32 id = 1; 
	string name = 2;
}
message Domain{
	int32 id = 1; 
	string name = 2;
	int32 age=3;
}

§3 使用

注册 ProtoBuf 编解码器

ch.pipeline().addLast(new ProtoBufEncoder(EntityPOJO.Entity.getDefaultInstance()));
ch.pipeline().addLast(new ProtoBufDecoder(DataInfo.Dispatcher.getDefaultInstance()));

创建对象并发送 (以混合类型为例)

DataInfo data = DataInfo.Dispatcher.newBuilder()
			.setDataType(DataInfo.Dispatcher.DataType.EntityType)
			.setEntity(DataInfo.Entity.newBuilder.setId(1).setName("name").build())
			.build();
ch.writeAndFlush(data);

接收对象 (以混合类型为例)

DataInfo.Dispatcher.DataType dataType = msg.getDataType();
if(DataInfo.Dispatcher.DataType.Entity == dataType){
	DataInfo.Entity entity = msg.getStudent();
	System.out.println("Entity: " + entity);
}else if(DataInfo.Dispatcher.DataType.Domain == dataType){
	// do
}else{
	// do 
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值