反射机制

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的反射机制的更多相关文章

  1. Java学习之反射机制及应用场景

    前言: 最近公司正在进行业务组件化进程,其中的路由实现用到了Java的反射机制,既然用到了就想着好好学习总结一下,其实无论是之前的EventBus 2.x版本还是Retrofit.早期的View注解框 ...

  2. 第28章 java反射机制

    java反射机制 1.类加载机制 1.1.jvm和类 运行Java程序:java 带有main方法的类名 之后java会启动jvm,并加载字节码(字节码就是一个类在内存空间的状态) 当调用java命令 ...

  3. NPOI操作EXCEL(四)——反射机制批量导出excel文件

    前面我们已经实现了反射机制进行excel表格数据的解析,既然有上传就得有下载,我们再来写一个通用的导出方法,利用反射机制实现对系统所有数据列表的筛选结果导出excel功能. 我们来构想一下这样一个画面 ...

  4. Java反射机制

    Java反射机制 一:什么事反射机制 简单地说,就是程序运行时能够通过反射的到类的所有信息,只需要获得类名,方法名,属性名. 二:为什么要用反射:     静态编译:在编译时确定类型,绑定对象,即通过 ...

  5. java基础知识(十一)java反射机制(上)

    java.lang.Class类详解 java Class类详解 一.class类 Class类是java语言定义的特定类的实现,在java中每个类都有一个相应的Class对象,以便java程序运行时 ...

  6. java基础知识(十一)java反射机制(下)

    1.什么是反射机制? java反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法,对于任意一个对象都能够调用他的属性和方法,这种动态获取属性和方法的功能称为java的反射机制. ...

  7. c#反射机制

    一:反射的定义 审查元数据并收集关于它的类型信息的能力.元数据(编译以后的最基本数据单元)就是一大堆的表,当编译程序集或者模块时,编译器会创建一个类定义表,一个字段定义表,和一个方法定义表等. Sys ...

  8. java反射学习之一反射机制概述

    一.反射机制背景概述 1.反射(reflection)是java被视为动态语言的一个关键性质 2.反射机制指的是程序在运行时能获取任何类的内部所有信息 二.反射机制实现功能概述 1.只要给定类的全名, ...

  9. Java中的反射机制

    Java反射机制 反射机制定义 反射机制是Java语言中一个非常重要的特性,它允许程序在运行时进行自我检查,同时也允许其对内部成员进行操作.由于反射机制能够实现在运行时对类进行装载,因此能够增加程序的 ...

随机推荐

  1. common tar command

    Compress tar -cvzf jy2653.2.tgz jy2653.2 Decompress tar -xvf jy2653.1.tgz

  2. poj 2503 Babelfish(字典树哈希)

    Time Limit: 3000MS Memory Limit: 65536K Total Submissions: 29059 Accepted: 12565 Description You hav ...

  3. (转载)PHP strtotime函数详解

    (转载)http://www.jb51.net/article/21495.htm strtotime函数是一个很好的函数,灵活的运用它,会给你的工作带来不少方便.但PHP的手册中却对此函数的参数没作 ...

  4. lightoj 1011 最大权重匹配或最大费用流

    由于暂时不会KM算法,只能用最大费用流来做了. 题目链接:http://lightoj.com/volume_showproblem.php?problem=1011 #include <cst ...

  5. LA 3263 欧拉定理

    题目链接:https://icpcarchive.ecs.baylor.edu/index.php?option=com_onlinejudge&Itemid=8&page=show_ ...

  6. Simpsons’ Hidden Talents - HDU 2594(求相同的前缀后缀)

    题目大意:给你两个字符串,找出一个最大的子串,这个子串要是前面串的前缀并且是后面串的后缀...........   分析:next的简单运用吧,可以把两个串进行合并,中间加一个不能被匹配的字符,然后求 ...

  7. Python随机生成验证码的两种方法

    Python随机生成验证码的方法有很多,今天给大家列举两种,大家也可以在这个基础上进行改造,设计出适合自己的验证码方法方法一:利用range Python随机生成验证码的方法有很多,今天给大家列举两种 ...

  8. oracle存储过程含参数的插入数据

    create or replace procedure proczipcodebyzipinsert(   i_zipcode  in  zipcode.zip%type,   i_city in z ...

  9. Rocketmq整体分析

    之前本人在实际的生产环境中,使用过activemq和rabbitmq消息队列,在使用过程中出现一些难以解决的问题,本文通过产品选型.网络架构和核心特性分析了rocketmq的优势和特性. 产品选型 我 ...

  10. 高效实现 std::string split() API

    Qt下一个 QString 实现split()性能.和std::string未实现它的.STL也未实现.只有自己可以写一. #include <string> #include <v ...