关于第二个问题:如何包装/扩展生成的AVRO java类以添加方法?
您可以使用AspectJ将新方法注入到现有/生成的类中。 AspectJ仅在编译时需要。方法如下所示。
定义一个人记录作为阿夫罗IDL(person.avdl):
@namespace("net.tzolov.avro.extend")
protocol PersonProtocol {
record Person {
string firstName;
string lastName;
}
}
使用行家和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() =名字+ 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行家插件来编织该方面与所生成的代码
<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());
}