﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>BlogJava-上善若水-随笔分类-Protobuf</title><link>http://www.blogjava.net/DLevin/category/54894.html</link><description>In general the OO style is to use a lot of little objects with a lot of little methods that give us a lot of plug points for overriding and variation.
To do is to be -Nietzsche, To bei is to do -Kant, Do be do be do -Sinatra</description><language>zh-cn</language><lastBuildDate>Mon, 03 Aug 2015 11:21:43 GMT</lastBuildDate><pubDate>Mon, 03 Aug 2015 11:21:43 GMT</pubDate><ttl>60</ttl><item><title>深入Protobuf源码－Descriptor、Message、RPC框架</title><link>http://www.blogjava.net/DLevin/archive/2015/04/01/424012.html</link><dc:creator>DLevin</dc:creator><author>DLevin</author><pubDate>Wed, 01 Apr 2015 01:31:00 GMT</pubDate><guid>http://www.blogjava.net/DLevin/archive/2015/04/01/424012.html</guid><wfw:comment>http://www.blogjava.net/DLevin/comments/424012.html</wfw:comment><comments>http://www.blogjava.net/DLevin/archive/2015/04/01/424012.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.blogjava.net/DLevin/comments/commentRss/424012.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/DLevin/services/trackbacks/424012.html</trackback:ping><description><![CDATA[<h2><span style="color: #ff6600;">Descriptor框架</span></h2><span style="font-size:12.0pt;font-family:SimSun;Times New Roman&quot;;Times New Roman&quot;;Times New Roman&quot;;">对非</span><span style="font-size:12.0pt; font-family:&quot;Times New Roman&quot;;">optimize_for</span><span style="font-size:12.0pt;font-family:SimSun;Times New Roman&quot;;Times New Roman&quot;;Times New Roman&quot;;">为</span><span style="font-size:12.0pt; font-family:&quot;Times New Roman&quot;;">LITE_RUNTIME</span><span style="font-size:12.0pt;font-family:SimSun;Times New Roman&quot;;Times New Roman&quot;;Times New Roman&quot;;">的</span><span style="font-size:12.0pt; font-family:&quot;Times New Roman&quot;;">proto</span><span style="font-size:12.0pt;font-family:SimSun;Times New Roman&quot;;Times New Roman&quot;;Times New Roman&quot;;">文件，</span><span style="font-size:12.0pt; font-family:&quot;Times New Roman&quot;;">protobuf</span><span style="font-size:12.0pt;font-family:SimSun;Times New Roman&quot;;Times New Roman&quot;;Times New Roman&quot;;">编译器会在编译出的</span><span style="font-size: 12.0pt;font-family:&quot;Times New Roman&quot;;">Java</span><span style="font-size:12.0pt;font-family:SimSun;Times New Roman&quot;;Times New Roman&quot;;Times New Roman&quot;;">代码文件末尾添加一个</span><span style="font-size: 12.0pt;font-family:&quot;Times New Roman&quot;;">FileDescriptor</span><span style="font-size:12.0pt;font-family:SimSun;Times New Roman&quot;;Times New Roman&quot;;Times New Roman&quot;;">静态字段以描述该</span><span style="font-size:12.0pt; font-family:&quot;Times New Roman&quot;;">proto</span><span style="font-size:12.0pt;font-family:SimSun;Times New Roman&quot;;Times New Roman&quot;;Times New Roman&quot;;">文件定义时的所有元数据信息、为每个</span><span style="font-size:12.0pt;font-family:&quot;Times New Roman&quot;;">message</span><span style="font-size:12.0pt;font-family:SimSun;Times New Roman&quot;;Times New Roman&quot;;Times New Roman&quot;;">对象定义一个</span><span style="font-size: 12.0pt;font-family:&quot;Times New Roman&quot;;">Descriptor</span><span style="font-size:12.0pt;font-family:SimSun;Times New Roman&quot;;Times New Roman&quot;;Times New Roman&quot;;">静态字段以描述该</span><span style="font-size:12.0pt; font-family:&quot;Times New Roman&quot;;">message</span><span style="font-size:12.0pt;font-family:SimSun;Times New Roman&quot;;Times New Roman&quot;;Times New Roman&quot;;">定义时的元数据信息、为每个</span><span style="font-size: 12.0pt;font-family:&quot;Times New Roman&quot;;">message</span><span style="font-size:12.0pt;font-family:SimSun;Times New Roman&quot;;Times New Roman&quot;;Times New Roman&quot;;">对象定义一个</span><span style="font-size:12.0pt; font-family:&quot;Times New Roman&quot;;">FieldAccessorTable</span><span style="font-size:12.0pt;font-family:SimSun;Times New Roman&quot;;Times New Roman&quot;;Times New Roman&quot;;">静态字段用于使用反射读取</span><span style="font-size: 12.0pt;font-family:&quot;Times New Roman&quot;;">/</span><span style="font-size:12.0pt;font-family:SimSun;Times New Roman&quot;;Times New Roman&quot;;Times New Roman&quot;;">设置某个字段的值等（以提供</span><span style="font-size: 12.0pt;font-family:&quot;Times New Roman&quot;;">GeneratedMessage</span><span style="font-size:12.0pt;font-family:SimSun;Times New Roman&quot;;Times New Roman&quot;;Times New Roman&quot;;">中方法的反射实现）：</span>&nbsp; &nbsp;&nbsp;<br /><div style="background-color:#eeeeee;font-size:13px;border:1px solid #CCCCCC;padding-right: 5px;padding-bottom: 4px;padding-left: 4px;padding-top: 4px;width: 98%;word-break:break-all"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="color: #0000FF; ">private</span>&nbsp;<span style="color: #0000FF; ">static</span>&nbsp;Descriptor&nbsp;inter-nal_static_levin_protobuf_Result_descriptor;<br /><span style="color: #0000FF; ">private</span>&nbsp;<span style="color: #0000FF; ">static</span>&nbsp;FieldAccessorTable&nbsp;inter-nal_static_levin_protobuf_Result_fieldAccessorTable;<br /><span style="color: #0000FF; ">private</span>&nbsp;<span style="color: #0000FF; ">static</span>&nbsp;Descriptor&nbsp;inter-nal_static_levin_protobuf_SearchResponse_descriptor;<br /><span style="color: #0000FF; ">private</span>&nbsp;<span style="color: #0000FF; ">static</span>&nbsp;FieldAccessorTable&nbsp;inter-nal_static_levin_protobuf_SearchResponse_fieldAccessorTable;<br /><span style="color: #0000FF; ">private</span>&nbsp;<span style="color: #0000FF; ">static</span>&nbsp;FileDescriptor&nbsp;descriptor;</div><p><span style="font-family:SimSun;Times New Roman&quot;;Times New Roman&quot;">在</span>protobuf<span style="font-family:SimSun;Times New Roman&quot;;Times New Roman&quot;">中存在多种类型的元数据描述类：</span></p>  <p style="margin-left:18.0pt;text-indent:-18.0pt;">1.<span style="font-stretch: normal; font-size: 7pt; line-height: normal; font-family: 'Times New Roman';">&nbsp;&nbsp;&nbsp;&nbsp; </span>FileDescriptor<span style="font-family:SimSun;Times New Roman&quot;;Times New Roman&quot;">：对一个</span>proto<span style="font-family:SimSun;Times New Roman&quot;;Times New Roman&quot;">文件的描述，它包含文件名、包名、选项（如</span>java_package<span style="font-family:SimSun;Times New Roman&quot;;Times New Roman&quot;">、</span>java_outer_classname<span style="font-family:SimSun;Times New Roman&quot;;Times New Roman&quot;">等）、文件中定义的所有</span>message<span style="font-family:SimSun;Times New Roman&quot;;Times New Roman&quot;">、文件中定义的所有</span>enum<span style="font-family:SimSun;Times New Roman&quot;;Times New Roman&quot;">、文件中定义的所有</span>service<span style="font-family:SimSun;Times New Roman&quot;;Times New Roman&quot;">、文件中所有定义的</span>extension<span style="font-family:SimSun;Times New Roman&quot;;Times New Roman&quot;">、文件中定义的所有依赖文件（</span>import<span style="font-family:SimSun;Times New Roman&quot;;Times New Roman&quot;">）等。在</span>FileDescriptor<span style="font-family:SimSun;Times New Roman&quot;;Times New Roman&quot;">中还存在一个</span>DescriptorPool<span style="font-family:SimSun;Times New Roman&quot;;Times New Roman&quot;">实例，它保存了所有的</span>dependencies(<span style="font-family:SimSun;Times New Roman&quot;;Times New Roman&quot;">依赖文件的</span>FileDescriptor)<span style="font-family:SimSun;Times New Roman&quot;;Times New Roman&quot;">、</span>name<span style="font-family:SimSun;Times New Roman&quot;;Times New Roman&quot;">到</span>GenericDescriptor<span style="font-family:SimSun;Times New Roman&quot;;Times New Roman&quot;">的映射、字段到</span>FieldDescriptor<span style="font-family:SimSun;Times New Roman&quot;;Times New Roman&quot;">的映射、枚举项到</span>EnumValueDescriptor<span style="font-family:SimSun;Times New Roman&quot;;Times New Roman&quot;">的映射，从而可以从该</span>DescriptorPool<span style="font-family:SimSun;Times New Roman&quot;;Times New Roman&quot;">中查找相关的信息，因而可以通过名字从</span>FileDescriptor<span style="font-family:SimSun;Times New Roman&quot;;Times New Roman&quot;">中查找</span>Message<span style="font-family:SimSun;Times New Roman&quot;;Times New Roman&quot;">、</span>Enum<span style="font-family:SimSun;Times New Roman&quot;;Times New Roman&quot;">、</span>Service<span style="font-family:SimSun;Times New Roman&quot;;Times New Roman&quot;">、</span>Extensions<span style="font-family:SimSun;Times New Roman&quot;;Times New Roman&quot;">等。</span></p>  <p style="margin-left:18.0pt;text-indent:-18.0pt;"><span style="font-family:&quot;MS Reference Sans Serif&quot;;MS Reference Sans Serif&quot;;MS Reference Sans Serif&quot;">2.<span style="font-stretch: normal; font-size: 7pt; line-height: normal; font-family: 'Times New Roman';">&nbsp;&nbsp; </span></span><span style="font-family:&quot;MS Reference Sans Serif&quot;;MS Reference Sans Serif&quot;">Descriptor</span><span style="font-family:SimSun;MS Reference Sans Serif&quot;;MS Reference Sans Serif&quot;;MS Reference Sans Serif&quot;">：对一个</span><span style="font-family:&quot;MS Reference Sans Serif&quot;;MS Reference Sans Serif&quot;">message</span><span style="font-family: SimSun;MS Reference Sans Serif&quot;;MS Reference Sans Serif&quot;;MS Reference Sans Serif&quot;">定义的描述，它包含该</span><span style="font-family:&quot;MS Reference Sans Serif&quot;;MS Reference Sans Serif&quot;">message</span><span style="font-family: SimSun;MS Reference Sans Serif&quot;;MS Reference Sans Serif&quot;;MS Reference Sans Serif&quot;">定义的名字、所有字段、内嵌</span><span style="font-family:&quot;MS Reference Sans Serif&quot;;MS Reference Sans Serif&quot;">message</span><span style="font-family: SimSun;MS Reference Sans Serif&quot;;MS Reference Sans Serif&quot;;MS Reference Sans Serif&quot;">、内嵌</span><span style="font-family:&quot;MS Reference Sans Serif&quot;;MS Reference Sans Serif&quot;">enum</span><span style="font-family:SimSun;MS Reference Sans Serif&quot;;MS Reference Sans Serif&quot;;MS Reference Sans Serif&quot;">、关联的</span><span style="font-family:&quot;MS Reference Sans Serif&quot;;MS Reference Sans Serif&quot;">FileDescriptor</span><span style="font-family:SimSun;MS Reference Sans Serif&quot;;MS Reference Sans Serif&quot;;MS Reference Sans Serif&quot;">等。可以使用字段名或字段号查找</span><span style="font-family:&quot;MS Reference Sans Serif&quot;;MS Reference Sans Serif&quot;">FieldDescriptor</span><span style="font-family:SimSun;MS Reference Sans Serif&quot;;MS Reference Sans Serif&quot;;MS Reference Sans Serif&quot;">。</span></p>  <p style="margin-left:18.0pt;text-indent:-18.0pt;"><span style="font-family:&quot;MS Reference Sans Serif&quot;;MS Reference Sans Serif&quot;;MS Reference Sans Serif&quot;">3.<span style="font-stretch: normal; font-size: 7pt; line-height: normal; font-family: 'Times New Roman';">&nbsp;&nbsp; </span></span><span style="font-family:&quot;MS Reference Sans Serif&quot;;MS Reference Sans Serif&quot;">FieldDescriptor</span><span style="font-family:SimSun;MS Reference Sans Serif&quot;;MS Reference Sans Serif&quot;;MS Reference Sans Serif&quot;">：对一个字段或扩展字段定义的描述，它包含字段名、字段号、字段类型、字段定义</span><span style="font-family:&quot;MS Reference Sans Serif&quot;;MS Reference Sans Serif&quot;">(required/optional/repeated/packed)</span><span style="font-family:SimSun;MS Reference Sans Serif&quot;;MS Reference Sans Serif&quot;;MS Reference Sans Serif&quot;">、默认值、是否是扩展字段以及和它关联的</span><span style="font-family:&quot;MS Reference Sans Serif&quot;;MS Reference Sans Serif&quot;">Descriptor/FileDescriptor</span><span style="font-family:SimSun;MS Reference Sans Serif&quot;;MS Reference Sans Serif&quot;;MS Reference Sans Serif&quot;">等。</span></p>  <p style="margin-left:18.0pt;text-indent:-18.0pt;"><span style="font-family:&quot;MS Reference Sans Serif&quot;;MS Reference Sans Serif&quot;;MS Reference Sans Serif&quot;">4.<span style="font-stretch: normal; font-size: 7pt; line-height: normal; font-family: 'Times New Roman';">&nbsp;&nbsp; </span></span><span style="font-family:&quot;MS Reference Sans Serif&quot;;MS Reference Sans Serif&quot;">EnumDescriptor</span><span style="font-family:SimSun;MS Reference Sans Serif&quot;;MS Reference Sans Serif&quot;;MS Reference Sans Serif&quot;">：对一个</span><span style="font-family:&quot;MS Reference Sans Serif&quot;;MS Reference Sans Serif&quot;">enum</span><span style="font-family:SimSun;MS Reference Sans Serif&quot;;MS Reference Sans Serif&quot;;MS Reference Sans Serif&quot;">定义的描述，它包含</span><span style="font-family:&quot;MS Reference Sans Serif&quot;;MS Reference Sans Serif&quot;">enum</span><span style="font-family:SimSun;MS Reference Sans Serif&quot;;MS Reference Sans Serif&quot;;MS Reference Sans Serif&quot;">名、全名、和它关联的</span><span style="font-family:&quot;MS Reference Sans Serif&quot;;MS Reference Sans Serif&quot;">FileDescriptor</span><span style="font-family:SimSun;MS Reference Sans Serif&quot;;MS Reference Sans Serif&quot;;MS Reference Sans Serif&quot;">。可以使用枚举项或枚举值查找</span><span style="font-family:&quot;MS Reference Sans Serif&quot;;MS Reference Sans Serif&quot;">EnumValueDescriptor</span><span style="font-family:SimSun;MS Reference Sans Serif&quot;;MS Reference Sans Serif&quot;;MS Reference Sans Serif&quot;">。</span></p>  <p style="margin-left:18.0pt;text-indent:-18.0pt;"><span style="font-family:&quot;MS Reference Sans Serif&quot;;MS Reference Sans Serif&quot;;MS Reference Sans Serif&quot;">5.<span style="font-stretch: normal; font-size: 7pt; line-height: normal; font-family: 'Times New Roman';">&nbsp;&nbsp; </span></span><span style="font-family:&quot;MS Reference Sans Serif&quot;;MS Reference Sans Serif&quot;">EnumValueDescriptor</span><span style="font-family:SimSun;MS Reference Sans Serif&quot;;MS Reference Sans Serif&quot;;MS Reference Sans Serif&quot;">：对一个枚举项定义的描述，它包含枚举名、枚举值、关联的</span><span style="font-family:&quot;MS Reference Sans Serif&quot;;MS Reference Sans Serif&quot;">EnumDescriptor/FileDescriptor</span><span style="font-family:SimSun;MS Reference Sans Serif&quot;;MS Reference Sans Serif&quot;;MS Reference Sans Serif&quot;">等。</span></p>  <p style="margin-left:18.0pt;text-indent:-18.0pt;"><span style="font-family:&quot;MS Reference Sans Serif&quot;;MS Reference Sans Serif&quot;;MS Reference Sans Serif&quot;">6.<span style="font-stretch: normal; font-size: 7pt; line-height: normal; font-family: 'Times New Roman';">&nbsp;&nbsp; </span></span><span style="font-family:&quot;MS Reference Sans Serif&quot;;MS Reference Sans Serif&quot;">ServiceDescriptor</span><span style="font-family:SimSun;MS Reference Sans Serif&quot;;MS Reference Sans Serif&quot;;MS Reference Sans Serif&quot;">：对一个</span><span style="font-family:&quot;MS Reference Sans Serif&quot;;MS Reference Sans Serif&quot;">service</span><span style="font-family: SimSun;MS Reference Sans Serif&quot;;MS Reference Sans Serif&quot;;MS Reference Sans Serif&quot;">定义的描述，它包含</span><span style="font-family:&quot;MS Reference Sans Serif&quot;;MS Reference Sans Serif&quot;">service</span><span style="font-family: SimSun;MS Reference Sans Serif&quot;;MS Reference Sans Serif&quot;;MS Reference Sans Serif&quot;">名、全名、关联的</span><span style="font-family:&quot;MS Reference Sans Serif&quot;;MS Reference Sans Serif&quot;">FileDescriptor</span><span style="font-family:SimSun;MS Reference Sans Serif&quot;;MS Reference Sans Serif&quot;;MS Reference Sans Serif&quot;">等。</span></p>  <p style="margin-left:18.0pt;text-indent:-18.0pt;"><span style="font-family:&quot;MS Reference Sans Serif&quot;;MS Reference Sans Serif&quot;;MS Reference Sans Serif&quot;">7.<span style="font-stretch: normal; font-size: 7pt; line-height: normal; font-family: 'Times New Roman';">&nbsp;&nbsp; </span></span><span style="font-family:&quot;MS Reference Sans Serif&quot;;MS Reference Sans Serif&quot;">MethodDescriptor</span><span style="font-family:SimSun;MS Reference Sans Serif&quot;;MS Reference Sans Serif&quot;;MS Reference Sans Serif&quot;">：对一个在</span><span style="font-family:&quot;MS Reference Sans Serif&quot;;MS Reference Sans Serif&quot;">service</span><span style="font-family: SimSun;MS Reference Sans Serif&quot;;MS Reference Sans Serif&quot;;MS Reference Sans Serif&quot;">中的</span><span style="font-family:&quot;MS Reference Sans Serif&quot;;MS Reference Sans Serif&quot;">method</span><span style="font-family: SimSun;MS Reference Sans Serif&quot;;MS Reference Sans Serif&quot;;MS Reference Sans Serif&quot;">的描述，它包含</span><span style="font-family:&quot;MS Reference Sans Serif&quot;;MS Reference Sans Serif&quot;">method</span><span style="font-family: SimSun;MS Reference Sans Serif&quot;;MS Reference Sans Serif&quot;;MS Reference Sans Serif&quot;">名、全名、参数类型、返回类型、关联的</span><span style="font-family:&quot;MS Reference Sans Serif&quot;;MS Reference Sans Serif&quot;">FileDescriptor/ServiceDescriptor</span><span style="font-family:SimSun;MS Reference Sans Serif&quot;;MS Reference Sans Serif&quot;;MS Reference Sans Serif&quot;">等。</span></p>  <p><span style="font-family:SimSun;Times New Roman&quot;;Times New Roman&quot;">最后，</span>protobuf<span style="font-family:SimSun;Times New Roman&quot;;Times New Roman&quot;">编译生成的代码末尾还有一个</span>descriptorData<span style="font-family:SimSun;Times New Roman&quot;;Times New Roman&quot;">字符串数组，它是序列化后的</span>FileDescriptorProto<span style="font-family:SimSun;Times New Roman&quot;;Times New Roman&quot;">数据，在静态初始化块中可以调用</span>FileDescriptor.internalBuildGeneratedFileFrom()<span style="font-family:SimSun;Times New Roman&quot;;Times New Roman&quot;">方法构造整个</span>FileDescriptor<span style="font-family:SimSun;Times New Roman&quot;;Times New Roman&quot;">实例，在完成</span>FileDescriptor<span style="font-family:SimSun;Times New Roman&quot;;Times New Roman&quot;">的构造后，还会回调传入的</span>InternalDescriptorAssigner<span style="font-family:SimSun;Times New Roman&quot;;Times New Roman&quot;">实例以初始化其他的静态字段，如以上提到的所有的静态字段。<br /><br /></span></p>  <p><span style="font-family:SimSun;Times New Roman&quot;;Times New Roman&quot;">在</span>protobuf<span style="font-family:SimSun;Times New Roman&quot;;Times New Roman&quot;">中</span>Descriptor<span style="font-family:SimSun;Times New Roman&quot;;Times New Roman&quot;">的类图：<br /><img src="http://www.blogjava.net/images/blogjava_net/dlevin/Descriptors_ClassDiagram.png" width="1566" height="1210" alt="" /><br /></span></p><br /><h2><span style="color: #ff6600;">Message、MessageLite框架</span></h2><p style="text-indent:21.25pt"><span style="font-family:SimSun;Times New Roman&quot;;Times New Roman&quot;;">序列化和反序列化是</span>protobuf<span style="font-family:SimSun;Times New Roman&quot;;Times New Roman&quot;">最基础的框架，</span><span style="font-family:&quot;Heiti SC Light&quot;;Times New Roman&quot;">它使用</span>MessageLite/Message<span style="font-family:&quot;Heiti SC Light&quot;;Times New Roman&quot;">接口来抽象一个可序列化的实例，</span><span style="font-family:&quot;Heiti SC Light&quot;;Times New Roman&quot;;">并且使用</span>Builder<span style="font-family:&quot;Heiti SC Light&quot;;Times New Roman&quot;;">从字节数组或输入字节流中构建</span>MessageLite/Message<span style="font-family:&quot;Heiti SC Light&quot;;Times New Roman&quot;;">实例，</span>MessageLite<span style="font-family:&quot;Heiti SC Light&quot;;Times New Roman&quot;;">和</span>Message<span style="font-family:&quot;Heiti SC Light&quot;;Times New Roman&quot;;">内部都定义了自己的</span>Builder<span style="font-family:&quot;Heiti SC Light&quot;;Times New Roman&quot;;">类，他们个字继承自</span>MessageLiteOrBuilder<span style="font-family:&quot;Heiti SC Light&quot;;Times New Roman&quot;;">以及</span>MessageOrBuiler<span style="font-family:&quot;Heiti SC Light&quot;;Times New Roman&quot;;">，它们定义了</span>MessageLite/Message<span style="font-family:&quot;Heiti SC Light&quot;;Times New Roman&quot;;">和它们各自</span>Builder<span style="font-family:&quot;Heiti SC Light&quot;;Times New Roman&quot;;">类的共同接口。</span></p>  <p style="text-indent:21.25pt">MessageLiteOrBuilder<span style="font-family:&quot;Heiti SC Light&quot;;Times New Roman&quot;;">接口只定义了</span>MessageLite<span style="font-family:&quot;Heiti SC Light&quot;;Times New Roman&quot;;">和</span>MessageLite.Builder<span style="font-family:&quot;Heiti SC Light&quot;;Times New Roman&quot;;">两个接口共有的两个方法：</span>getDefaultInstanceForType()<span style="font-family:&quot;Heiti SC Light&quot;;Times New Roman&quot;;">方法获取一个当前还未初始化的当前</span>Message<span style="font-family:&quot;Heiti SC Light&quot;;Times New Roman&quot;;">实例</span>(<span style="font-family: &quot;Heiti SC Light&quot;;Times New Roman&quot;;">没有字段被赋值，因而所有字段返回默认值，对</span>repeat<span style="font-family:&quot;Heiti SC Light&quot;;Times New Roman&quot;;">字段返回空，在当前</span>protobuf 2.5.0<span style="font-family:&quot;Heiti SC Light&quot;;Times New Roman&quot;;">的实现中，它返回的是一个单例，和每个生成的静态方法</span>getDefaultInstance()<span style="font-family:&quot;Heiti SC Light&quot;;Times New Roman&quot;;">返回相同的实例</span>)<span style="font-family: &quot;Heiti SC Light&quot;;Times New Roman&quot;;">；</span>isInitialized()<span style="font-family: &quot;Heiti SC Light&quot;;Times New Roman&quot;;">方法用来判断是否所有</span>required<span style="font-family:&quot;Heiti SC Light&quot;;Times New Roman&quot;;">字段已经被赋值。</span>MessageLite<span style="font-family:&quot;Heiti SC Light&quot;;Times New Roman&quot;;">接口中定义了两个</span>writeTo()<span style="font-family:&quot;Heiti SC Light&quot;;Times New Roman&quot;;">方法分别将当前实例序列化并写入输出字节流中，而另一个</span>writeDelimitedTo()<span style="font-family:&quot;Heiti SC Light&quot;;Times New Roman&quot;;">方法则在写入之前将当前实例的总长度写入输出字节流中（以可变长</span>32<span style="font-family:&quot;Heiti SC Light&quot;;Times New Roman&quot;;">位</span>Int<span style="font-family:&quot;Heiti SC Light&quot;;Times New Roman&quot;;">编码方式），从而可以同时向一个输出字节流中写入多个</span>Message<span style="font-family:&quot;Heiti SC Light&quot;;Times New Roman&quot;;">实例；</span>MessageLite<span style="font-family:&quot;Heiti SC Light&quot;;Times New Roman&quot;;">中还定义了获取当前</span>MessageLite<span style="font-family:&quot;Heiti SC Light&quot;;Times New Roman&quot;;">在序列化成字节流后的总字节数的方法</span>getSerializedSize()<span style="font-family:&quot;Heiti SC Light&quot;;Times New Roman&quot;;">，两个直接返回字节数组的</span>toByteArray()/toByteString()<span style="font-family:&quot;Heiti SC Light&quot;;Times New Roman&quot;;">方法，以及获取它的</span>Parser<span style="font-family:&quot;Heiti SC Light&quot;;Times New Roman&quot;;">实例</span>(getParserForType())<span style="font-family:&quot;Heiti SC Light&quot;;Times New Roman&quot;;">和返回它的</span>Builder<span style="font-family:&quot;Heiti SC Light&quot;;Times New Roman&quot;;">实例</span>(toBuilder()<span style="font-family:&quot;Heiti SC Light&quot;;Times New Roman&quot;;">－创建一个新的</span>Builder<span style="font-family:&quot;Heiti SC Light&quot;;Times New Roman&quot;;">实例</span>/newBuilderForType()<span style="font-family:&quot;Heiti SC Light&quot;;Times New Roman&quot;;">－用当前</span>MessageLite<span style="font-family:&quot;Heiti SC Light&quot;;Times New Roman&quot;;">类初始化一个新的</span>Builder<span style="font-family:&quot;Heiti SC Light&quot;;Times New Roman&quot;;">实例并返回</span>)<span style="font-family: &quot;Heiti SC Light&quot;;Times New Roman&quot;;">方法。其中</span>Builder<span style="font-family:&quot;Heiti SC Light&quot;;Times New Roman&quot;;">接口用于从字节流或字节数组中解析并构造</span>MessageLite<span style="font-family:&quot;Heiti SC Light&quot;;Times New Roman&quot;;">对象</span>(<span style="font-family:&quot;Heiti SC Light&quot;;Times New Roman&quot;;">各种版本的</span>mergeFrom()<span style="font-family:&quot;Heiti SC Light&quot;;Times New Roman&quot;;">方法，如果发送端写入了</span>MessageLite<span style="font-family:&quot;Heiti SC Light&quot;;Times New Roman&quot;;">字节长度，则使用</span>mergeDelimitedFrom()<span style="font-family:&quot;Heiti SC Light&quot;;Times New Roman&quot;;">方法</span>)<span style="font-family: &quot;Heiti SC Light&quot;;Times New Roman&quot;;">，最后</span>Builder<span style="font-family:&quot;Heiti SC Light&quot;;Times New Roman&quot;;">使用</span>build()<span style="font-family:&quot;Heiti SC Light&quot;;Times New Roman&quot;;">方法构造</span>MessageLite<span style="font-family:&quot;Heiti SC Light&quot;;Times New Roman&quot;;">对象，此时如果有</span>required<span style="font-family:&quot;Heiti SC Light&quot;;Times New Roman&quot;;">字段还未被设置，会抛出</span>UninitializedMessageException<span style="font-family:&quot;Heiti SC Light&quot;;Times New Roman&quot;;">，为了避免抛出异常，可以使用</span>buildPartial()<span style="font-family:&quot;Heiti SC Light&quot;;Times New Roman&quot;;">方法；另外</span>Builder<span style="font-family:&quot;Heiti SC Light&quot;;Times New Roman&quot;;">还定义了</span>clone()<span style="font-family:&quot;Heiti SC Light&quot;;Times New Roman&quot;;">和</span>clear()<span style="font-family:&quot;Heiti SC Light&quot;;Times New Roman&quot;;">方法；在生成的每个</span>Message<span style="font-family:&quot;Heiti SC Light&quot;;Times New Roman&quot;;">对象中都定义了一个</span>newBuilder()<span style="font-family:&quot;Heiti SC Light&quot;;Times New Roman&quot;;">静态方法，一般使用该静态方法初始化一个</span>Builder<span style="font-family:&quot;Heiti SC Light&quot;;Times New Roman&quot;;">实例。</span>Parser<span style="font-family:&quot;Heiti SC Light&quot;;Times New Roman&quot;;">接口也定义了各个版本的</span>parseFrom()/parsePartialFrom()/parseDelimitedFrom()/parsePartialDelimitedFrom()<span style="font-family:&quot;Heiti SC Light&quot;;Times New Roman&quot;;">方法用来从字节数组或字节流中解析出</span>Message<span style="font-family:&quot;Heiti SC Light&quot;;Times New Roman&quot;;">实例，在生成的代码中，</span>Builder<span style="font-family:&quot;Heiti SC Light&quot;;Times New Roman&quot;;">的实现直接调用</span>Parser<span style="font-family:&quot;Heiti SC Light&quot;;Times New Roman&quot;;">实现类中的方法。</span></p>  <p style="text-indent:21.25pt"><span style="font-family:&quot;Heiti SC Light&quot;;Times New Roman&quot;;">在大部分情况下，</span>MessageLite<span style="font-family:&quot;Heiti SC Light&quot;;Times New Roman&quot;;">已经能完成所有的序列化和反序列化操作了，特别是一些资源有限额手持设备，它如果运行整个</span>protobuf<span style="font-family:&quot;Heiti SC Light&quot;;Times New Roman&quot;;">库会显得太耗资源；可以在</span>.proto<span style="font-family:&quot;Heiti SC Light&quot;;Times New Roman&quot;;">文件中加入一下指令来告诉</span>protobuf<span style="font-family:&quot;Heiti SC Light&quot;;Times New Roman&quot;;">编译器只需要生成实现</span>MessageLite<span style="font-family:&quot;Heiti SC Light&quot;;Times New Roman&quot;;">的类：</span></p>  <p>option optimize_for = LITE_RUNTIME</p>  <p><span style="font-family:&quot;Heiti SC Light&quot;;Times New Roman&quot;;">然而对一般的</span>Server<span style="font-family:&quot;Heiti SC Light&quot;;Times New Roman&quot;;">程序来说，我们并不在乎这点资源的损耗，因而会选择实现</span>Message<span style="font-family:&quot;Heiti SC Light&quot;;Times New Roman&quot;;">接口，它相比</span>MessageLite<span style="font-family:&quot;Heiti SC Light&quot;;Times New Roman&quot;;">，添加了</span>Descriptors<span style="font-family:&quot;Heiti SC Light&quot;;Times New Roman&quot;;">相关的支持，即支持使用</span>FieldDescriptor<span style="font-family:&quot;Heiti SC Light&quot;;Times New Roman&quot;;">来构建</span>Message.Builder<span style="font-family:&quot;Heiti SC Light&quot;;Times New Roman&quot;;">实例并最终构建</span>Message<span style="font-family:&quot;Heiti SC Light&quot;;Times New Roman&quot;;">实例。</span></p>  <p style="text-indent:21.25pt">MessageOrBuilder<span style="font-family:&quot;Heiti SC Light&quot;;Times New Roman&quot;;">接口继承自</span>MessageLiteOrBuilder<span style="font-family:&quot;Heiti SC Light&quot;;Times New Roman&quot;;">接口，它定义了</span>Message<span style="font-family:&quot;Heiti SC Light&quot;;Times New Roman&quot;;">和</span>Message.Builder<span style="font-family:&quot;Heiti SC Light&quot;;Times New Roman&quot;;">共有的接口，即添加了</span>Descriptor<span style="font-family:&quot;Heiti SC Light&quot;;Times New Roman&quot;;">、</span>FieldDescriptor<span style="font-family:&quot;Heiti SC Light&quot;;Times New Roman&quot;;">等相关的扩展。由于实现</span>Message<span style="font-family:&quot;Heiti SC Light&quot;;Times New Roman&quot;;">和</span>Message.Builder<span style="font-family:&quot;Heiti SC Light&quot;;Times New Roman&quot;;">接口的类保存了所有</span>Message<span style="font-family:&quot;Heiti SC Light&quot;;Times New Roman&quot;;">定义时具有的信息</span>(<span style="font-family: &quot;Heiti SC Light&quot;;Times New Roman&quot;;">文件名、包名、字段列表等，使用各种</span>Descriptor<span style="font-family:&quot;Heiti SC Light&quot;;Times New Roman&quot;;">类来抽象</span>)<span style="font-family: &quot;Heiti SC Light&quot;;Times New Roman&quot;;">，因而我们可以使用</span>Message/Message.Builder<span style="font-family:&quot;Heiti SC Light&quot;;Times New Roman&quot;;">类获取到更多的信息，如一个</span>Message/Message.Builder<span style="font-family:&quot;Heiti SC Light&quot;;Times New Roman&quot;;">没有赋值所有</span>required<span style="font-family:&quot;Heiti SC Light&quot;;Times New Roman&quot;;">的字段，可以使用</span>findInitializationErrors()<span style="font-family:&quot;Heiti SC Light&quot;;Times New Roman&quot;;">方法来获取所有未赋值的字段列表</span>(<span style="font-family:&quot;Heiti SC Light&quot;;Times New Roman&quot;;">字段的全路径名，</span>getInitializationErrorString()<span style="font-family:&quot;Heiti SC Light&quot;;Times New Roman&quot;;">是这个列表的字符串形式表达，为了提升性能，建议使用</span>isInitialized()<span style="font-family:&quot;Heiti SC Light&quot;;Times New Roman&quot;;">方法先做初步判断，因为它更快</span>)<span style="font-family:&quot;Heiti SC Light&quot;;Times New Roman&quot;;">；另外在</span>MessageOrBuilder<span style="font-family:&quot;Heiti SC Light&quot;;Times New Roman&quot;;">中还定义了当前</span>Message<span style="font-family:&quot;Heiti SC Light&quot;;Times New Roman&quot;;">对应的</span>Descriptor<span style="font-family:&quot;Heiti SC Light&quot;;Times New Roman&quot;;">实例：</span>getDescriptorForType()<span style="font-family:&quot;Heiti SC Light&quot;;Times New Roman&quot;;">方法，获取所有已经赋值的</span>FieldDescriptor<span style="font-family:&quot;Heiti SC Light&quot;;Times New Roman&quot;;">到其值的一个</span>Map<span style="font-family: &quot;Heiti SC Light&quot;;Times New Roman&quot;;">：</span>getAllFields()<span style="font-family:&quot;Heiti SC Light&quot;;Times New Roman&quot;;">，通过</span>FieldDescriptor<span style="font-family:&quot;Heiti SC Light&quot;;Times New Roman&quot;;">取得其值：</span>getField()<span style="font-family:&quot;Heiti SC Light&quot;;Times New Roman&quot;;">，判断一个字段是否已经被赋值：</span>hasField()<span style="font-family:&quot;Heiti SC Light&quot;;Times New Roman&quot;;">，获取</span>repeated<span style="font-family:&quot;Heiti SC Light&quot;;Times New Roman&quot;;">字段的</span>count<span style="font-family:&quot;Heiti SC Light&quot;;Times New Roman&quot;;">：</span>getRepeatedFieldCount()<span style="font-family:&quot;Heiti SC Light&quot;;Times New Roman&quot;;">，通过</span>FieldDescriptor<span style="font-family:&quot;Heiti SC Light&quot;;Times New Roman&quot;;">以及</span>index<span style="font-family:&quot;Heiti SC Light&quot;;Times New Roman&quot;;">获取</span>repeated<span style="font-family:&quot;Heiti SC Light&quot;;Times New Roman&quot;;">字段在</span>index<span style="font-family:&quot;Heiti SC Light&quot;;Times New Roman&quot;;">处的值：</span>getRepeatedField()<span style="font-family:&quot;Heiti SC Light&quot;;Times New Roman&quot;;">，获取未知的字段：</span>getUnknownFields()<span style="font-family:&quot;Heiti SC Light&quot;;Times New Roman&quot;;">。</span>Message<span style="font-family:&quot;Heiti SC Light&quot;;Times New Roman&quot;;">接口除了继承自</span>MessageOrBuilder<span style="font-family:&quot;Heiti SC Light&quot;;Times New Roman&quot;;">接口的方法，并没有定义多余的方法，只是添加了</span>equals<span style="font-family:&quot;Heiti SC Light&quot;;Times New Roman&quot;;">、</span>hashCode<span style="font-family:&quot;Heiti SC Light&quot;;Times New Roman&quot;;">、</span>toString<span style="font-family:&quot;Heiti SC Light&quot;;Times New Roman&quot;;">方法的定义。而</span>Message.Builder<span style="font-family:&quot;Heiti SC Light&quot;;Times New Roman&quot;;">接口除了继承自</span>MessageOrBuilder<span style="font-family:&quot;Heiti SC Light&quot;;Times New Roman&quot;;">接口以外，它还定义了基于</span>FieldDescriptor<span style="font-family:&quot;Heiti SC Light&quot;;Times New Roman&quot;;">的方法，如通过</span>FieldDescriptor<span style="font-family:&quot;Heiti SC Light&quot;;Times New Roman&quot;;">创建</span>/<span style="font-family: &quot;Heiti SC Light&quot;;Times New Roman&quot;;">获取</span>Builder<span style="font-family:&quot;Heiti SC Light&quot;;Times New Roman&quot;;">实例：</span>newBuilderForFileld()/getFieldBuilder()<span style="font-family: &quot;Heiti SC Light&quot;;Times New Roman&quot;;">，通过</span>FieldDescriptor<span style="font-family: &quot;Heiti SC Light&quot;;Times New Roman&quot;;">设置</span>/<span style="font-family:&quot;Heiti SC Light&quot;;Times New Roman&quot;;">清除字段的值：</span>setField()/clearField()/setRepeatedField()/addRepeatedField()<span style="font-family:&quot;Heiti SC Light&quot;;Times New Roman&quot;;">，以及设置</span>UnknownFields<span style="font-family:&quot;Heiti SC Light&quot;;Times New Roman&quot;;">：</span>setUnknownFields()/mergeUnknownFields()<span style="font-family:&quot;Heiti SC Light&quot;;Times New Roman&quot;;">。</span></p>  <p>&nbsp;</p>  <p>MessageLite/Message<span style="font-family: &quot;Heiti SC Light&quot;;Times New Roman&quot;;">类图如下：</span></p><img src="http://www.blogjava.net/images/blogjava_net/dlevin/Message_Framework_ClassDiagram.png" width="1269" height="941" alt="" /><br /><br /><h2><span style="color: #ff6600;">RPC框架</span></h2><p style="text-indent:21.25pt"><span style="font-family:&quot;Heiti SC Light&quot;;Times New Roman&quot;;">除了序列化框架，</span>protobuf<span style="font-family:&quot;Heiti SC Light&quot;;Times New Roman&quot;;">还定义了一套简单的</span>RPC<span style="font-family:&quot;Heiti SC Light&quot;;Times New Roman&quot;;">框架。之所以说简单是因为它定义的</span>Service<span style="font-family:&quot;Heiti SC Light&quot;;Times New Roman&quot;;">层接口的协议，而没有具体和传输相关的实现，而只是将传输相关的逻辑抽象成</span>RpcChannel<span style="font-family:&quot;Heiti SC Light&quot;;Times New Roman&quot;;">和</span>BlockingRpcChannel<span style="font-family:&quot;Heiti SC Light&quot;;Times New Roman&quot;;">分别用于表示同步和一步方式的</span>Service<span style="font-family:&quot;Heiti SC Light&quot;;Times New Roman&quot;;">方法调用，而至于底层用什么样的协议和框架，由用户自己决定并实现。</span></p>  <p style="text-indent:21.25pt"><span style="font-family:&quot;Heiti SC Light&quot;;Times New Roman&quot;;">所谓</span>RPC<span style="font-family:&quot;Heiti SC Light&quot;;Times New Roman&quot;;">框架，从用户角度上最基本的就是定义客户端和服务器端的协议，即服务器端暴露出什么样的接口供客户端调用，这个接口定义了服务器在一个</span>Host<span style="font-family:&quot;Heiti SC Light&quot;;Times New Roman&quot;;">的某个（些）端口上接收某些请求数据，并期望能返回的响应。其中服务器和端口号属于传输实现的范畴，</span>protobuf<span style="font-family:&quot;Heiti SC Light&quot;;Times New Roman&quot;;">只是用</span>RpcChannel/BlockingRpcChannel<span style="font-family:&quot;Heiti SC Light&quot;;Times New Roman&quot;;">的概念做了抽象，而没有给出具体实现；而接收某个请求数据以及期待的响应数据，在</span>protobuf<span style="font-family:&quot;Heiti SC Light&quot;;Times New Roman&quot;;">使用</span>Service/BlockingService<span style="font-family:&quot;Heiti SC Light&quot;;Times New Roman&quot;;">抽象来定义，并且这也是</span>protobuf<span style="font-family:&quot;Heiti SC Light&quot;;Times New Roman&quot;;">中</span>RPC<span style="font-family: &quot;Heiti SC Light&quot;;Times New Roman&quot;;">框架的定义部分，其中</span>Service<span style="font-family:&quot;Heiti SC Light&quot;;Times New Roman&quot;;">和</span>RpcChannel<span style="font-family:&quot;Heiti SC Light&quot;;Times New Roman&quot;;">共同构成异步方式的</span>RPC<span style="font-family:&quot;Heiti SC Light&quot;;Times New Roman&quot;;">框架，而</span>BlockingService<span style="font-family:&quot;Heiti SC Light&quot;;Times New Roman&quot;;">和</span>BlockingRpcChannel<span style="font-family:&quot;Heiti SC Light&quot;;Times New Roman&quot;;">共同构成了同步（阻塞）方式的</span>RPC<span style="font-family:&quot;Heiti SC Light&quot;;Times New Roman&quot;;">框架。</span></p>  <p style="text-indent:21.25pt"><span style="font-family:&quot;Heiti SC Light&quot;;Times New Roman&quot;;">从底层实现的角度，一个</span>RPC<span style="font-family:&quot;Heiti SC Light&quot;;Times New Roman&quot;;">调用就是客户端发送一些请求数据给服务器，服务器解析并处理这些请求数据，然后将响应数据返回给客户端。为了隐藏内部实现细节，提升写代码的效率，</span>RPC<span style="font-family:&quot;Heiti SC Light&quot;;Times New Roman&quot;;">将这一过程封装成方法调用，即不同的请求用不同的方法表达，这就是</span>protobuf<span style="font-family:&quot;Heiti SC Light&quot;;Times New Roman&quot;;">中</span>RPC<span style="font-family:&quot;Heiti SC Light&quot;;Times New Roman&quot;;">的定义。在</span>protobuf<span style="font-family:&quot;Heiti SC Light&quot;;Times New Roman&quot;;">中，定义一个</span>PRC<span style="font-family: &quot;Heiti SC Light&quot;;Times New Roman&quot;;">接口比较简单：首先开启</span>RPC<span style="font-family:&quot;Heiti SC Light&quot;;Times New Roman&quot;;">功能，然后用</span>service<span style="font-family:&quot;Heiti SC Light&quot;;Times New Roman&quot;;">关键字定义一个接口，在接口中使用</span>rpc<span style="font-family:&quot;Heiti SC Light&quot;;Times New Roman&quot;;">关键字定义一个方法，方法包含方法名、方法参数、返回值，其中方法参数和返回值都必须是一个</span>message<span style="font-family:&quot;Heiti SC Light&quot;;Times New Roman&quot;;">类型，并且只能有一个：</span></p><div style="font-size: 13px; border: 1px solid #cccccc; padding: 4px 5px 4px 4px; width: 98%; word-break: break-all; background-color: #eeeeee;"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />-->option&nbsp;java_generic_services&nbsp;=&nbsp;<span style="color: #0000FF; ">true</span>;<br /><br />service&nbsp;MyService&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;rpc&nbsp;request(SearchRequest)&nbsp;returns(SearchResponse);<br />}</div><p><span style="font-family:&quot;Heiti SC Light&quot;;Times New Roman&quot;;">在</span>protobuf<span style="font-family:&quot;Heiti SC Light&quot;;Times New Roman&quot;;">编译生成的代码中，它会生成一个</span>MyService<span style="font-family:&quot;Heiti SC Light&quot;;Times New Roman&quot;;">抽象类实现了</span>Service<span style="font-family:&quot;Heiti SC Light&quot;;Times New Roman&quot;;">接口，一般它只是作为一个命名空间，它内部定义了两个接口：</span>Interface<span style="font-family:&quot;Heiti SC Light&quot;;Times New Roman&quot;;">和</span>BlockingInterface<span style="font-family:&quot;Heiti SC Light&quot;;Times New Roman&quot;;">本别继承自</span>Service<span style="font-family:&quot;Heiti SC Light&quot;;Times New Roman&quot;;">接口和</span>BlockingService<span style="font-family:&quot;Heiti SC Light&quot;;Times New Roman&quot;;">接口，用于抽象异步和同步方式的</span>RPC<span style="font-family:&quot;Heiti SC Light&quot;;Times New Roman&quot;;">方法调用；这两个接口有两个实现类：</span>Stub<span style="font-family:&quot;Heiti SC Light&quot;;Times New Roman&quot;;">和</span>BlockingStub<span style="font-family:&quot;Heiti SC Light&quot;;Times New Roman&quot;;">，他们分别接收</span>RpcChannel<span style="font-family:&quot;Heiti SC Light&quot;;Times New Roman&quot;;">和</span>BlockingRpcChannel<span style="font-family:&quot;Heiti SC Light&quot;;Times New Roman&quot;;">实例作为构造函数参数，可以使用</span>MyService<span style="font-family:&quot;Heiti SC Light&quot;;Times New Roman&quot;;">中的静态方法</span>newStub()<span style="font-family:&quot;Heiti SC Light&quot;;Times New Roman&quot;;">和</span>newBlockingStub()<span style="font-family:&quot;Heiti SC Light&quot;;Times New Roman&quot;;">方法获取他们各自实例，他们主要用于客户端的调用。在生成的</span>request<span style="font-family:&quot;Heiti SC Light&quot;;Times New Roman&quot;;">方法中，除了</span>request<span style="font-family:&quot;Heiti SC Light&quot;;Times New Roman&quot;;">本身的参数，还有一个</span>RpcController<span style="font-family:&quot;Heiti SC Light&quot;;Times New Roman&quot;;">参数，它用于处理在</span>RpcChannel/BlockingRpcChannel<span style="font-family:&quot;Heiti SC Light&quot;;Times New Roman&quot;;">调用中的状态处理，如错误处理等，使用它可以获知此次调用是否出错，错误信息是什么等。在</span>MyService<span style="font-family:&quot;Heiti SC Light&quot;;Times New Roman&quot;;">中还定义了两个静态方法</span>newReflectiveService/newReflectiveBlockingService<span style="font-family:&quot;Heiti SC Light&quot;;Times New Roman&quot;;">，他们接收</span>Interface/BlockingInterface<span style="font-family:&quot;Heiti SC Light&quot;;Times New Roman&quot;;">实例，并返回</span>Service/BlockingService<span style="font-family:&quot;Heiti SC Light&quot;;Times New Roman&quot;;">的实现实例（暂时还没有想到使用他们的场景）。</span></p><img src="http://www.blogjava.net/images/blogjava_net/dlevin/RPC_Framework.png" width="1027" height="775" alt="" /><br /><br /><p style="text-indent:21.25pt"><span style="font-family:&quot;Heiti SC Light&quot;;Times New Roman&quot;;">在</span>MyService<span style="font-family:&quot;Heiti SC Light&quot;;Times New Roman&quot;;">的</span>RPC<span style="font-family:&quot;Heiti SC Light&quot;;Times New Roman&quot;;">框架实现中，在服务器端，实现</span>MyService.Interface/MyService.BlockingInterface<span style="font-family:&quot;Heiti SC Light&quot;;Times New Roman&quot;;">接口，然后将它注册到对</span>RpcChannel/BlockingRpcChannel<span style="font-family:&quot;Heiti SC Light&quot;;Times New Roman&quot;;">框架的实现中；在客户端则创建一个</span>RpcChannel/BlockingRpcChannel<span style="font-family:&quot;Heiti SC Light&quot;;Times New Roman&quot;;">实例，传入</span>MyService.newStub()/MyService.newBlockingStub()<span style="font-family:&quot;Heiti SC Light&quot;;Times New Roman&quot;;">方法获取对应的实例，然后使用这个</span>Stub/BlockingStub<span style="font-family:&quot;Heiti SC Light&quot;;Times New Roman&quot;;">实例调用相应的方法即可。</span></p><img src ="http://www.blogjava.net/DLevin/aggbug/424012.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/DLevin/" target="_blank">DLevin</a> 2015-04-01 09:31 <a href="http://www.blogjava.net/DLevin/archive/2015/04/01/424012.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>深入Protobuf源码－编码实现</title><link>http://www.blogjava.net/DLevin/archive/2015/04/01/424011.html</link><dc:creator>DLevin</dc:creator><author>DLevin</author><pubDate>Wed, 01 Apr 2015 01:23:00 GMT</pubDate><guid>http://www.blogjava.net/DLevin/archive/2015/04/01/424011.html</guid><wfw:comment>http://www.blogjava.net/DLevin/comments/424011.html</wfw:comment><comments>http://www.blogjava.net/DLevin/archive/2015/04/01/424011.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.blogjava.net/DLevin/comments/commentRss/424011.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/DLevin/services/trackbacks/424011.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 基本类型编码在前文有提到消息是一系列的基本类型以及其他消息类型的组合，因而基本类型是probobuf编码实现的基础，这些基本类型有：          .proto Type         Java Type         C++ Type         Wire Type             double         double         double         WI...&nbsp;&nbsp;<a href='http://www.blogjava.net/DLevin/archive/2015/04/01/424011.html'>阅读全文</a><img src ="http://www.blogjava.net/DLevin/aggbug/424011.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/DLevin/" target="_blank">DLevin</a> 2015-04-01 09:23 <a href="http://www.blogjava.net/DLevin/archive/2015/04/01/424011.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>深入Protobuf源码－概述、使用以及代码生成实现</title><link>http://www.blogjava.net/DLevin/archive/2015/04/01/424009.html</link><dc:creator>DLevin</dc:creator><author>DLevin</author><pubDate>Wed, 01 Apr 2015 01:13:00 GMT</pubDate><guid>http://www.blogjava.net/DLevin/archive/2015/04/01/424009.html</guid><wfw:comment>http://www.blogjava.net/DLevin/comments/424009.html</wfw:comment><comments>http://www.blogjava.net/DLevin/archive/2015/04/01/424009.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/DLevin/comments/commentRss/424009.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/DLevin/services/trackbacks/424009.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 概述捣鼓hdfs、yarn、hbase、zookeeper的代码一年多了，是时候整理一下了。在hadoop （2.5.2）中protobuf是节点之间以及客户端和各个节点通信的基础序列化框架（协议），而基于avro和Writable的序列化框架则是这个协议里的payload，因而这一系列的文章打算从protobuf这个框架开始入手(版本2.5.0)。从抽象的角度来说，protobuf框架是...&nbsp;&nbsp;<a href='http://www.blogjava.net/DLevin/archive/2015/04/01/424009.html'>阅读全文</a><img src ="http://www.blogjava.net/DLevin/aggbug/424009.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/DLevin/" target="_blank">DLevin</a> 2015-04-01 09:13 <a href="http://www.blogjava.net/DLevin/archive/2015/04/01/424009.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>