protobuf的反射机制
反射机制
java在运行状态时,能够知道任意类的所有属性和方法,都能够调用任意对象的任意方法和属性。这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。
C++本身没有反射机制。protobuf通过proto文件生成相应的message和service,protobuf也通过proto文件提供反射机制,程序在运行时可以通过proto获取任意message和任意service的属性和方法,也可以在运行时调用message的属性和方法。
获取message和service的属性和方法
protobuf通过Descriptor获取任意message或service的属性和方法,Descriptor主要包括了以下集中类型:
FileDescriptor 获取proto文件中的Descriptor和ServiceDescriptor
Descriptor 获取类message属性和方法,包括FieldDescriptor 和 EnumDescriptor等
FieldDescriptor 获取message中各个字段的类型、标签、名称等
EnumDescriptor 获取Enum中的各个字段名称、值等
ServiceDescriptor 获取service中的MethodDescriptor
MethodDescriptor 获取各个rpc中的request、response、名称等
当我们获得proto文件的FileDescriptor时,我们就可以获得所有的service的Descriptor和service的ServiceDescriptor,进而获取其相应的字段或rpc。也就是说,如果能获取到proto文件的FileDescriptor,就能所有的proto文件中的所有内容。
那么如何获取proto文件的FileDescriptor呢?protobuf对应以下两种不同的情况提供了相应的办法
1、 使用protoc将proto文件并生成相应的.h和.cpp文件。
这中情况下protobuf已经解析好proto文件,并将所有的Descriptor放在DescriptorPool中了。,可以根据proto的文件名,通过DescriptorPool获取到相应的FileDescriptor,例如,现有test.proto文件,那么可以通过DescriptorPool::generated_pool()获取到其FileDescriptor。其实,对于任意的message和service,也都可以根据其名称,通过DescriptorPool获取相应的Descriptor和ServiceDescriptor。例如:

2、 只有proto文件,不使用protoc。
这种情况需要去手动解析proto文件,然后再获取FileDescriptor。还好protobuf提供了相应的解析器compiler,通过compiler可以很方便得获取proto文件的FileDescriptor,具体如下:

调用message的属性和方法
想要调用message的属性和方法,就得先获取相应的message对象。protobuf的message对象都是放在MessageFactory中的,可以通过Descriptor,具体如下:

有了message对象,并不能直接调用其对象和方法,因为所有的message对象都是Message*类型的,但不同的message对象的属性和方法是不一样的,在这里,Message*只是指向相应的message大小的地址空间,并不知道对应的message中到底有哪些属性和方法。
protobuf是通过Reflection调用message的属性和方法的。message中的方法只有对各个属性的get和set,而调用message的属性其实也就是调用属性的get。调用message的某一个属性的get,就需要该属性的Descriptor,通过Reflection获取message获取相应的值;调用message某一属性的set,也需要该属性的Descriptor,通过Reflection将相应的值写入到message相应的属性。例如:


反射机制的应用
有了反射机制,可以写很多工具,比如:基于pb的自动化测试工具、pb转json或xml的工具、pb直接写到数据库的工具等。反射只是一种机制,有什么样的应用场景需要你的想象力!
protobuf的反射机制的更多相关文章
- Java学习之反射机制及应用场景
前言: 最近公司正在进行业务组件化进程,其中的路由实现用到了Java的反射机制,既然用到了就想着好好学习总结一下,其实无论是之前的EventBus 2.x版本还是Retrofit.早期的View注解框 ...
- 第28章 java反射机制
java反射机制 1.类加载机制 1.1.jvm和类 运行Java程序:java 带有main方法的类名 之后java会启动jvm,并加载字节码(字节码就是一个类在内存空间的状态) 当调用java命令 ...
- NPOI操作EXCEL(四)——反射机制批量导出excel文件
前面我们已经实现了反射机制进行excel表格数据的解析,既然有上传就得有下载,我们再来写一个通用的导出方法,利用反射机制实现对系统所有数据列表的筛选结果导出excel功能. 我们来构想一下这样一个画面 ...
- Java反射机制
Java反射机制 一:什么事反射机制 简单地说,就是程序运行时能够通过反射的到类的所有信息,只需要获得类名,方法名,属性名. 二:为什么要用反射: 静态编译:在编译时确定类型,绑定对象,即通过 ...
- java基础知识(十一)java反射机制(上)
java.lang.Class类详解 java Class类详解 一.class类 Class类是java语言定义的特定类的实现,在java中每个类都有一个相应的Class对象,以便java程序运行时 ...
- java基础知识(十一)java反射机制(下)
1.什么是反射机制? java反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法,对于任意一个对象都能够调用他的属性和方法,这种动态获取属性和方法的功能称为java的反射机制. ...
- c#反射机制
一:反射的定义 审查元数据并收集关于它的类型信息的能力.元数据(编译以后的最基本数据单元)就是一大堆的表,当编译程序集或者模块时,编译器会创建一个类定义表,一个字段定义表,和一个方法定义表等. Sys ...
- java反射学习之一反射机制概述
一.反射机制背景概述 1.反射(reflection)是java被视为动态语言的一个关键性质 2.反射机制指的是程序在运行时能获取任何类的内部所有信息 二.反射机制实现功能概述 1.只要给定类的全名, ...
- Java中的反射机制
Java反射机制 反射机制定义 反射机制是Java语言中一个非常重要的特性,它允许程序在运行时进行自我检查,同时也允许其对内部成员进行操作.由于反射机制能够实现在运行时对类进行装载,因此能够增加程序的 ...
随机推荐
- 「Poetize9」礼物运送
3055: 礼物运送 Time Limit: 3 Sec Memory Limit: 128 MBSubmit: 18 Solved: 12[Submit][Status] Description ...
- UVA- 1504 - Genghis Khan the Conqueror(最小生成树-好题)
题意: n个点,m个边,然后给出m条边的顶点和权值,其次是q次替换,每次替换一条边,给出每次替换的边的顶点和权值,然后求出这次替换的最小生成树的值; 最后要你输出:q次替换的平均值.其中n<30 ...
- (转载)php flush()刷新不能输出缓冲的原因分析
(转载)http://www.webkaka.com/tutorial/php/2012/110628/ 在php程序编写中,flush()的使用率还是挺高的,它在网页表现即时信息效果时发挥了极为重要 ...
- 连接Oracle的几种方式
如何引用Data.OracleClient.dll 由于从.net 4.0之后,微软将OracleClient.dll从框架里去除了,所以要使用,需要在VS2010里面去把项目的.net框架从.net ...
- 高效算法——Bin Packing F - 贪心
Time Limit:3000MS Memory Limit:0KB 64bit IO Format:%lld & %llu Submit Status Descripti ...
- cf602A Two Bases
A. Two Bases time limit per test 1 second memory limit per test 256 megabytes input standard input o ...
- Android按钮式进度条
package com.example.progress.demo; import android.annotation.SuppressLint; import android.content.Co ...
- 网络编程之TCP异步群聊:服务器端代码
最近朋友建议我写一些关于微软云技术的博客留给学校下一届的学生们看,怕下一届的MSTC断档.于是我也觉的有这个必要.写了几篇博客之后,我觉得也有必要把这一年的学习内容放在博客做个纪念,就这样写了本篇博客 ...
- 自己去看dubbo源码
编译Dubbo源码并测试 2014.09.24 | Comments 转http://blog.javachen.com/2014/09/24/compile-and-test-dubbo.html ...
- Angular2学习
1.新建项目 2.新建Model public class TodoItem { public int Id { get; set; } public string Key { get; set; } ...