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语言中一个非常重要的特性,它允许程序在运行时进行自我检查,同时也允许其对内部成员进行操作.由于反射机制能够实现在运行时对类进行装载,因此能够增加程序的 ...
随机推荐
- HDU 3829 Cat VS Dog(最大独立集)
题目大意: 有n只猫,有m只狗.现在有P个学生去参观动物园.每个孩子有喜欢的动物和不喜欢的动物.假如他喜欢猫那么他就一定不喜欢狗(反之亦然). 如果一个孩子喜欢一个动物,那么这个动物不会被移除,若是不 ...
- 【动态规划】Codeforces 711C Coloring Trees
题目链接: http://codeforces.com/problemset/problem/711/C 题目大意: 给N棵树,M种颜色,已经有颜色的不能涂色,没颜色为0,可以涂色,每棵树I涂成颜色J ...
- 【模拟】Codeforces 691A Fashion in Berland
题目链接: http://codeforces.com/problemset/problem/691/A 题目大意: n个数0或1,要求恰好n-1个1,如果n为1则那个数一定要是1 题目思路: [模拟 ...
- HDU4099 Revenge of Fibonacci(高精度+Trie)
Revenge of Fibonacci Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 204800/204800 K (Java/ ...
- + (void)load和+ (void)initialize有什么用处
两个方法都可以进行一些类的初始化操作.其中有些小区别.+(void)load 方法只要加入了工程种,进行了编译,且.m中实现了这个方法,都会调用一次,值得注意的时没实现的子类是不会调用的,就算父类实现 ...
- UITextField知多少
//初始化textfield并设置位置及大小 UITextField *text = [[UITextField alloc]initWithFrame:CGRectMake(20, 20, 130, ...
- Intellij调试debug
先编译好要调试的程序. 1.设置断点 选定要设置断点的代码行,在行号的区域后面单击鼠标左键即可. 2.开启调试会话 点击红色箭头指向的小虫子,开始进入调试. IDE下方出现Debug视图,红色的箭头指 ...
- 用urllib2实现一个下载器的思路
下载器的构造 用urllib2实现下载器时从以下几个层面实现功能和灵活性: handler redirect, cookie, proxy 动作 timeout 构造请求 headers: ua, c ...
- oracle存储过程含参数的插入数据
create or replace procedure proczipcodebyzipinsert( i_zipcode in zipcode.zip%type, i_city in z ...
- 谁动了我的timer?——C#的垃圾回收和调试
先来看如下的一段代码: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 using System; using System.Threading; publi ...