上篇已經(jīng)簡單的分析了什么是ProtoBuf協(xié)議的優(yōu)缺點、簡單的環(huán)境配置、項目中的簡單使用和一些編寫.Proto文件的注意點桃熄,下面我們更加深入一下ProtoBuf的語法及高級使用(非常感謝Carson_Ho大神的博文指導(dǎo))
從Google官方例子進(jìn)行語法深入
Google官方例子:
syntax = "proto2";//聲明proto版本着茸,2.0與3.0以后語法差異很大
package tutorial;//// 關(guān)注1:包名
option java_package = "com.example.tutorial";
option java_outer_classname = "AddressBookProtos";//// 關(guān)注2:option選項
message Person {//// 關(guān)注3:消息模型
required string name = 1;
required int32 id = 2;
optional string email = 3;
enum PhoneType {
MOBILE = 0;
HOME = 1;
WORK = 2;
}
message PhoneNumber {
required string number = 1;
optional PhoneType type = 2 [default = HOME];
}
repeated PhoneNumber phones = 4;
}
message AddressBook {
repeated Person people = 1;
}
針對上述官方例子的注釋,下面一一分析
關(guān)注點1:包名
作用:防止不同 .proto 項目間命名 發(fā)生沖突
ProtoBuf包的解析過程如下
:
- Protocol buffer 的類型名稱解析與 C++ 一致:從 最內(nèi)部 開始查找樟澜,依次 向外 進(jìn)行
每個包會被看作是其父類包的內(nèi)部類
- Protocol buffer 編譯器會解析 .proto文件中定義的所有類型名
生成器會根據(jù) 不同語言 生成 對應(yīng)語言 的代碼文件 - 即對 不同語言 使用了 不同的規(guī)則 進(jìn)行處理
- Protoco Buffer提供 C++误窖、Java、Python 三種語言的 API
關(guān)注點2:option選項
作用:影響 特定環(huán)境下 的處理方式秩贰,但不改變整個文件聲明的含義
常用Option選項
:(因為使用有限霹俺,簡單列舉常見的)
option java_package = "com.crf.jason.myapplication";
// 定義:Java包名
// 作用:指定生成的類應(yīng)該放在什么Java包名下
// 注:如不顯式指定,默認(rèn)包名為:按照應(yīng)用名稱倒序方式進(jìn)行排序
option java_outer_classname="Demo";
// 定義:類名
// 作用:生成對應(yīng).java 文件的類名(不能跟下面message的類名相同)
// 注:如不顯式指定萍膛,則默認(rèn)為把.proto文件名轉(zhuǎn)換為首字母大寫來生成
// 如.proto文件名="book.proto"吭服,默認(rèn)情況下,將使用 "BookOuterClass" 做為類名
option optimize_for = ***;
// 作用:影響 C++ & java 代碼的生成
// ***參數(shù)如下:
// 1. SPEED (默認(rèn))::protocol buffer編譯器將通過在消息類型上執(zhí)行序列化蝗罗、語法分析及其他通用的操作艇棕。(最優(yōu)方式)
// 2. CODE_SIZE::編譯器將會產(chǎn)生最少量的類,通過共享或基于反射的代碼來實現(xiàn)序列化串塑、語法分析及各種其它操作沼琉。
// 特點:采用該方式產(chǎn)生的代碼將比SPEED要少很多, 但是效率較低桩匪;
// 使用場景:常用在 包含大量.proto文件 但 不追求效率 的應(yīng)用中打瘪。
//3. LITE_RUNTIME::編譯器依賴于運(yùn)行時 核心類庫 來生成代碼(即采用libprotobuf-lite 替代libprotobuf)。
// 特點:這種核心類庫要比全類庫小得多(忽略了 一些描述符及反射 );編譯器采用該模式產(chǎn)生的方法實現(xiàn)與SPEED模式不相上下闺骚,產(chǎn)生的類通過實現(xiàn) MessageLite接口彩扔,但它僅僅是Messager接口的一個子集。
// 應(yīng)用場景:移動手機(jī)平臺應(yīng)用
- Google官方還提供了在ProtoBuf中允許 自定義選項并且使用,具體請參考:傳送門
關(guān)注點3:消息模型
作用:真正用于描述 數(shù)據(jù)結(jié)構(gòu)
在.proto消息模型中主要有 消息對象&字段
Protobuf中的消息對象
- 一個消息對象(Message) = 一個 結(jié)構(gòu)化數(shù)據(jù)
- 消息對象用 修飾符 message 修飾
- 消息對象 含有 字段:消息對象(Message)里的 字段 = 結(jié)構(gòu)化數(shù)據(jù) 里的成員變量
注意:
-
在一個.proto文件可以定義多個消息對象
message Person{//level 0 string name=1; int32 age=2; string email=3; ... } message Car{ string carName=1; int32 price=2; }
-
在一個消息對象里面可以定義另外一個消息對象(嵌套)
message Person{//level 0 string name=1; int32 age=2; string email=3; enum Phonetype{ MOBILE=0; HOME=1; } message PhoneNumber{//level 1 string number=1; } }
Protobuf中消息對象的字段
字段
組成:字段 = 字段修飾符 + 字段類型 +字段名 +標(biāo)識號(主要針對proto2以前版本)
// required int32 id = 1;
字段 = 字段類型 +字段名 +標(biāo)識號(主要針對proto3及以后版本)
int32 id = 1;
字段類型
一個消息對象 可以將 其他消息對象類型 用作字段類型
使用同一個 .proto 文件里的消息類型
-
使用 內(nèi)部消息類型
先在 消息類型 中定義 其他消息類型 僻爽,然后再使用(嵌套) message Person{//level 0 string name=1; int32 age=2; string email=3; enum Phonetype{ MOBILE=0; HOME=1; } message PhoneNumber{//level 1 string number=1; Person person=2; } PhoneNumber phoneNumber=4;//這里就是直接使用剛才定義的PhoneNumber消息類型 } message Car{ string carName=1; int32 price=2; Person.PhoneNumber phoneNumber=3; }
-
使用 外部消息類型
即外部重用虫碉,需要 用作字段類型的消息類型 定義在 該消息類型外部 message Person{//level 0 string name=1; int32 age=2; string email=3; enum Phonetype{ MOBILE=0; HOME=1; } message PhoneNumber{//level 1 string number=1; Person person=2;//這里就是使用外部消息類型 person } PhoneNumber phoneNumber=4; } message Car{ string carName=1; int32 price=2; Person.PhoneNumber phoneNumber=3; }
-
使用 外部消息的內(nèi)部消息類型
message Person{//level 0 string name=1; int32 age=2; string email=3; enum Phonetype{ MOBILE=0; HOME=1; } message PhoneNumber{//level 1 string number=1; Person person=2; } PhoneNumber phoneNumber=4; } message Car{ string carName=1; int32 price=2; Person.PhoneNumber phoneNumber=3;//這里使用外部消息類型Person的PhoneNumber內(nèi)部消息類型 }
-
使用不同 .proto 文件里的消息類型
作用:需要在 A.proto文件 使用 B.proto文件里的消息類型
在 A.proto文件 通過導(dǎo)入( import) B.proto文件中來使用 B.proto文件 里的消息類型
-
將 消息對象類型 用在 RPC(遠(yuǎn)程方法調(diào)用)系統(tǒng)
具體實現(xiàn)請移步:大神博客
關(guān)于ProtoBuf在項目中的實踐的高級用法請關(guān)注:下一篇博客:在項目中使用Protobuf協(xié)議實現(xiàn)數(shù)據(jù)傳輸(三)