关于第二个问题:如何包装/扩展生成的 AVRO java 类以添加方法?
您可以使用 AspectJ 将新方法注入现有/生成的类。只有在编译时才需要 AspectJ。方法如下所示。
将 Person 记录定义为 Avro IDL ( person.avdl ):
@namespace("net.tzolov.avro.extend")
protocol PersonProtocol {
record Person {
string firstName;
string lastName;
}
}
使用 maven 和avro-maven-plugin从 AVDL 生成 java 源代码:
<dependency>
<groupId>org.apache.avro</groupId>
<artifactId>avro</artifactId>
<version>1.6.3</version>
</dependency>
......
<plugin>
<groupId>org.apache.avro</groupId>
<artifactId>avro-maven-plugin</artifactId>
<version>1.6.3</version>
<executions>
<execution>
<id>generate-avro-sources</id>
<phase>generate-sources</phase>
<goals>
<goal>idl-protocol</goal>
</goals>
<configuration>
<sourceDirectory>src/main/resources/avro</sourceDirectory>
<outputDirectory>${project.build.directory}/generated-sources/java</outputDirectory>
</configuration>
</execution>
</executions>
</plugin>
以上配置假定person.avid文件位于src/main/resources/avro中。源在target/generated-sources/java中生成中生成。
生成的 Person.java 有两个方法:getFirstName() 和 getLastName()。如果你想用另一种方法扩展它:getCompleteName() = firstName + lastName 那么你可以用以下方面注入这个方法:
package net.tzolov.avro.extend;
import net.tzolov.avro.extend.Person;
public aspect PersonAspect {
public String Person.getCompleteName() {
return this.getFirstName() + " " + this.getLastName();
}
}
使用aspectj-maven-plugin maven 插件来编织这个切面和生成的代码
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjrt</artifactId>
<version>1.6.12</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.6.12</version>
</dependency>
....
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>aspectj-maven-plugin</artifactId>
<version>1.2</version>
<dependencies>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjrt</artifactId>
<version>1.6.12</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjtools</artifactId>
<version>1.6.12</version>
</dependency>
</dependencies>
<executions>
<execution>
<goals>
<goal>compile</goal>
<goal>test-compile</goal>
</goals>
</execution>
</executions>
<configuration>
<source>6</source>
<target>6</target>
</configuration>
</plugin>
结果:
@Test
public void testPersonCompleteName() throws Exception {
Person person = Person.newBuilder()
.setFirstName("John").setLastName("Atanasoff").build();
Assert.assertEquals("John Atanasoff", person.getCompleteName());
}