使用注解生成代码

一、概述

       生成源代码很容易,但是生成正确的源代码就不容易了。要使用优雅高效的方法来生成源代码将是一个繁重的任务。

 

幸运的是从去年开始,MDE[1](Model-Driven Engineering,也就是模型驱动工程设计,有时候也称为模型驱动开发或者模型驱动架构)已经有助于实践这个目标。这种设计更多的是倾向于艺术层面而不是科学——它针对的是经验丰富的程序员(译注:原文此句为task for ninja coders,国外有把经验丰富的程序员比作忍者的习惯)——是基于经过验证的流程和工具所提取出来的成熟方法论。

 

尽管我们可以认为生成源代码是MDE方法论的一个天然切入点,但是MDE涵盖的范围远远不止这些。

 

注解处理器只是众多我们用来生成源代码工具中的其中一种而已。

      

二、MDE中的ModelMeta-model

在开始讲解如何使用注解处理器生成源代码相关细节之前,这里有几个我们需要先了解的概念,因为在接下来的章节中我们将会使用这些概念:model(模型)和meta-model(元模型)。

 

MDE的一个重要支柱就是它抽象的结构。我们将想要创建的软件系统在不同的细节层面使用不同的方法进行建模。当对一个抽象层建模之后,我们就可以对下一个和再下一个层面继续建模,直到一个可部署的产品被完整地建立起来。

 

从这个角度来看,无论我们使用的是哪一个细节层面,一个模型(覆盖的范围)都不会超过对应用来代表系统的抽象层。

 

元模型(meta-model),就是我们用来定义模型的规则。你可以认为它是模型的schema或者语法。

三、过注解处理器生成源代码

    从一开始讨论到现在,注解处理器无疑是一种定义元模型和创建模型的优秀方法。注解类型扮演的是元模型角色,而一段代码块中所有注解的集合扮演的则是一个模型的角色。

我们可以利用模型来生成配置文件或者从一个已存在的源文件中派生出一个新的源文件。例如,创建一个远程代理,或者为被注解的bean创建一个可访问内部数据的入口对象。

这种方法的核心在于注解处理器。一个处理器能够读取源代码中的所有注解——也就是提取模型,并且通过它能够做任何我们想要做的事情——打开文件并添加内容等。Java编译器会处理好模型验证的问题(注解必须匹配在注解处理器中注册的类型)。

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

 

 

本教程由尚硅谷教育大数据研究院出品,如需转载请注明来源。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值