是否可以将运行时未知的Avro消息转换为特定的Java类

时间:2016-12-08 11:11:23

标签: java spring avro spring-amqp spring-rabbit

我正在研究Avro作为在Java应用程序中发布事件的序列化格式。

我想做的是将一些Avro字节转换为我使用Avro Maven插件生成的特定Java类的实例,反之亦然。

我想这样做是因为它允许使用我的代码的开发人员订阅特定事件并接收表示该特定事件的特定生成类的实例(可能将其从一个特定事件转发到Event类)对象,但不必触及任何Avro特定代码)。

我可以通过使用SpecificDatumReader编写代码并传入生成的类来指定我期望的类,以特定的方式执行此操作。不幸的是,这需要为每个生成的类编写代码。另一种方法是使用GenericDatumReader,但这不会给我一个我想要的生成类的实例。我想我想要在这两个解决方案之间找到一些东西,将特定对象作为输出,但具有通用方法的灵活性。

我正在考虑一个解决方案,在其中我检查序列化消息的模式并为此创建一个SpecificDatumReader,然后创建生成的类的实例。

这可能吗?我该怎么做?任何帮助表示赞赏!

一些更具体的上下文信息:我在Spring应用程序中使用RabbitMQ发布和订阅这些事件。 Spring提供RabbitTemplate以便于使用RabbitMQ,此类允许您设置MessageConverter。我想要做的是创建一个通用的MessageConverter,它使用我创建的Avro模式将字节转换为许多可能的Java对象(由Maven插件生成)和Java对象转换为字节。后者(对象到字节)听起来可行,但我不知道如何去做前者(字节到对象)。

2016年12月29日更新 :所有建议的解决方案都不适合我们。最终我们离开了Avro并寻求完全不同的解决方案。因此,我不接受建议的答案,因为它没有帮助我,我无法保证其正确性。

1 个答案:

答案 0 :(得分:0)

没有Avro API可以从Avro二进制编码中获取记录类型,因为Avro二进制编码没有该数据。通过按照声明的顺序对其字段的值进行编码来对记录进行编码。换句话说,记录被编码为其字段编码的串联。字段值按其架构进行编码。这就是为什么必须提供Avro最初用于编码数据的模式以便对其进行解码的原因。

由于Avro二进制编码输出的字节不指定记录类型,因此必须沿着Avro的二进制编码数据发送记录类型。将发送到RabbitMQ的消息更改为(1)用于编码数据的模式和(2)Avro二进制编码数据的组合。如果您不通过包含架构来消除消息大小,则可以包含架构的标识符。消费者程序将通过schema registry中的标识符检索模式。自定义MessageConverter可以从邮件中提取架构,以查看邮件中的多种记录类型。