使用注解生成代码
四、Filer
在本系列的第二部分中曾经提到,每一个处理器都能够获取到一个processing environment对象,通过它能够获取到一些有趣的工具类对象。其中一个就是Filer。
在javax.annotation.processing.Filer[2]接口中定义了一些创建源文件、class文件或者生成资源的方法。通过使用Filer,我们可以确保使用了正确的文件目录,以避免丢失文件系统中生成的一些重要数据。
(另外,)我们需要关注的重点:一方面是考虑是否要写一个在javac上附加-d或者-s选项的生成器,另一方面就是Maven POM中定义文件夹。
下面是一个如何在注解处理器中创建Java源文件的例子。正如我们创建了一个Bean信息类,生成的类名与被注解的类名相同,只是在它后面添加上了“BeanInfo”后缀:
if (e.getKind() == ElementKind.CLASS) {
TypeElement classElement = (TypeElement) e;
PackageElement packageElement =
(PackageElement) classElement.getEnclosingElement();
JavaFileObject jfo = processingEnv.getFiler().createSourceFile(
classElement.getQualifiedName() + "BeanInfo");
BufferedWriter bw = new BufferedWriter(jfo.openWriter());
bw.append("package ");
bw.append(packageElement.getQualifiedName());
bw.append(";");
bw.newLine();
bw.newLine();
// rest of generated class contents
}
上面的例子非常简单有趣,但是很糟糕。
我们将从注解中获取所需信息(代表模型)的逻辑与生成文件(代表视图,译注:指的是MVC设计模式中的V层)的逻辑混合在一起。
使用这种方法很难写出一个像样的生成器。如果我们需要在这个过程加入更复杂的东西,那么这个过程就会变得非常繁杂,并且容易出错,也很难维护。
因此,我们需要一种更加优雅的方式:
将模型从视图中清晰的分离出来。
使用模板来减轻生成文件的任务压力。
让我们来看一个使用这种方式的例子:如何利用Apache Velocity来生成我们想要的生成器。