有没有可能编写一个Avro schema/IDL来生成一个扩展基类或实现接口的Java类?看起来生成的Java类扩展了org.apache.avro.specific.SpecificRecordBase。因此,工具可能是要走的路。但是,我不知道这是否可能。
我见过一些例子,建议在每个特定的模式中定义一个显式的"type“字段,这种关联比继承语义更具关联性。
我在工厂类和带有<T extends BaseObject>等泛型的代码的其他部分中大量使用基类。目前,我让它从支持继承的JSON Schema中生成代码。
另一个附带问题:您是否可以使用IDL来定义没有协议定义的记录?我认为答案是否定的,因为编译器会抱怨缺少协议关键字。
感谢您的帮助!谢谢。
发布于 2014-01-10 11:27:21
我找到了一个更好的方法来解决这个问题。查看Avro中的Schema生成源,我发现在内部类生成逻辑使用Velocity模式来生成类。
我修改了record.vm模板以实现我的特定接口。有一种方法可以使用maven构建插件中的templateDirectory配置来指定velocity目录的位置。
我也改用SpecificDatumWriter而不是reflectDatumWriter。
<plugin>
<groupId>org.apache.avro</groupId>
<artifactId>avro-maven-plugin</artifactId>
<version>${avro.version}</version>
<executions>
<execution>
<phase>generate-sources</phase>
<goals>
<goal>schema</goal>
</goals>
<configuration>
<sourceDirectory>${basedir}/src/main/resources/avro/schema</sourceDirectory>
<outputDirectory>${basedir}/target/java-gen</outputDirectory>
<fieldVisibility>private</fieldVisibility>
<stringType>String</stringType>
<templateDirectory>${basedir}/src/main/resources/avro/velocity-templates/</templateDirectory>
</configuration>
</execution>
</executions>
</plugin>发布于 2018-11-25 08:21:28
我发现这个问题也有类似的问题。在我的例子中,我只需要对某些类型施加标记接口(稍后区分特定的类)。感谢你的回答,我深入研究了record.vm模板的结构。我发现可以在"javaAnnotation": "my.full.AnnotationName"定义JSON中定义.avsc键。然后将@my.full.AnnotationName添加到生成的类中。
诚然,这个解决方案最终不是建立在标记接口上的,尽管对于我的目的来说已经足够好了,保持模板不变是一个很大的优势。
发布于 2014-01-03 16:02:05
我决定使用Schema在运行时从类生成ReflectData,然后使用ReflectDatumWriter进行序列化。反射的使用将会更慢。但是,看起来该模式是在内部缓存的。如果我看到性能问题,我会报告的。
Schema schema = ReflectData.AllowNull.get().getSchema(sourceObject.getClass());
ReflectDatumWriter<T> reflectDatumWriter = new ReflectDatumWriter<>(schema);
DataFileWriter<T> writer = new DataFileWriter<>(reflectDatumWriter);
try {
writer.setCodec(CodecFactory.snappyCodec());
writer.create(schema, new File("data.avro"));
writer.append(sourceObject);
writer.close();
}
catch (IOException e) {
// log exception
}https://stackoverflow.com/questions/20864470
复制相似问题