Protobuf 动态创建对象

准备用netty+protobuf做一个通讯模块.

在netty官网找到一个LocalTime的一个demo,

class LocalTimeServerPipelineFactory implements ChannelPipelineFactory {
 
     public ChannelPipeline getPipeline() throws Exception {
         ChannelPipeline p = Channels.pipeline();
         p.addLast("frameDecoder", new ProtobufVarint32FrameDecoder());
         p.addLast("protobufDecoder", new ProtobufDecoder(LocalTimeProtocol.Locations.getDefaultInstance()));
         p.addLast("frameEncoder", new ProtobufVarint32LengthFieldPrepender());
         p.addLast("protobufEncoder", new ProtobufEncoder());
         p.addLast("handler", new LocalTimeServerHandler());
         return p;
     }

发现 ProtobufDecoder  是需要一个MessageLite 对象的,也就是要指定所要解析的对象类型,

但在一般应用中这样写死一个对象类型,所有业务中都用这一个数据结构是不太现实的(虽然protobuf是比较灵活的数据结构,但感觉还是会比较臃肿),然后就找动态创建Message 的方法,在官方文档中一眼就看到了一个 DynamicMessage 的对象,里边有findMessageTypeByName(name) ,parserFrom 等来构造消息的方法,很明显肯定就是这个了...

但是所有方法里都会有一个必须的参数 Descriptor 类型的对象,

连到源码中看见他是在Descriptors中的一个内部类

里边有FileDescriptor FieldDescriptor MethodDescriptor  EnumDescriptor ServiceDescriptor Descriptor ...

一眼可以看出来这有点类似于java 的反射  Type Field Method ....

FileDescriptor 可以在protobuf 生成的java文件中的静态方法获取到

name.proto Name.getDescriptor();

FileDescriptor file = Project.getDescriptor();
String name = "ByteCode";
Descriptor type = file.findMessageTypeByName(name);
System.out.println(type);
DynamicMessage msg = DynamicMessage.getDefaultInstance(type);

这是我一个Project.proto  文件里有一个 message 为 ByteCode 对象所生成的(有一点要注意的是它不需要包名).

最后担心一个问题是 DynamicMessage 的一些操作可能是要走反射的..


Hi,

I was trying to make Protobuf message self describing and also use the fact that in c++ we can get the instance of the exact message type from the name.

 const Descriptor* d = DescriptorPool::generated_

pool()->FindMessageTypeByName ("Message Name") ;
 Message * msg = MessageFactory::generated_ factory()->GetPrototype(d)-> New() ;
 msg->ParseFromString("Message data") ;

This seems to work for me well.

But I'm not able to find the equivalent implementation in Java. Is it possible to do the same in Java ?

- Suresh


============================================================


There is no central repository of descriptors in Java.  It wouldn't really work because Java normally does not load classes until they are first used, so the descriptors wouldn't appear in the repository until you manually loaded the classes somehow.


Instead, you should just create a Map<String, Descriptor> and populate it yourself.  It's easy to write a routine which will automatically loop through a whole FileDescriptor and even recurse through its dependencies to make this as simple as possible.



  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值