使用注解生成代码

、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来生成我们想要的生成器。