office

位置:IT落伍者 >> office >> 浏览文章

设计心得——用 XDoclet 减少代码膨胀


发布日期:2021年11月01日
 
设计心得——用 XDoclet 减少代码膨胀

开放源代码的 XDoclet 代码生成引擎是许多领先的 Java 框架不可缺少的组成部分常常被用作面向属性的编程和持续集成的引擎但是 XDoclet 还有一些不太惹人注目的地方对初级开发人员来说它太难掌握太难精通在这篇文章中流行作者 Sing Li 以 XDoclet 为对象揭示了其内部简单却优雅的设计使您能够理解这项技术并将它应用在实践当中

XDoclet 能够很容易成为您的 Java 编程工具箱中的一个更加通用的跨技术代码生成工具不幸的是开发人员经常忽视 XDoclet 的一般用途只有将它捆绑在大型开发框架或者 IDE 中作为其中的一个隐藏元素时才会用到它人们常常认为很难将 XDoclet 应用在定制解决方案上这篇文章的目的就是要消除这个迷惑把 XDoclet 从常见的复杂陷阱中解脱出来并向您展示了如何能够利用这个代码生成引擎

我会用一个实际的例子演示 XDoclet 的用途该例子将接收一个 POJO(plain old Java object)并用 XDoclet 生成完整 Web 应用程序的全部文件这些文件是把数据输入关系数据库所必需的该示例使用了 XDoclet 的 自定义模板代码生成功能以及它对 Hibernate 对象关系映射工具Struct Web 应用程序框架和应用程序服务器的内部支持(请参阅 参考资料)

智能代码生成器

XDoclet 的核心功能是根据以下组合来生成代码的(或者生成其他配置/数据文件)

进行特殊标记的 Java 源文件

预先定义的模板

与其他基于模板的代码生成技术(例如 Velocity请参阅 参考资料)相比XDoclet 具有以下独特优势

XDoclet 与 Apache Ant(请参阅 参考资料)紧密集成从而提供了高度自动化的操作

把控制代码生成和模板处理的 XDoclet 标签作为内联注释嵌入到 Java 源代码文件中这消除了同步多个相关文件和控制文件的需要

XDoclet 的内置 Java 解析器使用它对 Java 代码结构的深入理解为输入的 Java 代码建立内部 结构模型该结构模型又经常被叫作 元数据(metadata)因为它包含与关联代码有关的数据

XDoclet 的模板生成逻辑拥有对输入 Java 代码的内部结构模型的完全访问权

接下来我将进一步研究 XDoclet 是如何工作的以帮助您理解这些特性

XDoclet 操作

显示了 XDoclet 要求的输入和生成的输出

XDoclet 黑盒子

您可以看到包含嵌入式 XDoclet 标签的 Java 源代码是系统的输入在 Apache Ant 的驱动下XDoclet 处理输入的代码生成的输出文本文件可以是 Java 源代码HTML 页面XML 文件等为了处理输入XDoclet 需要使用模板(保存在 xdt 文件中)和标签处理器(用 Java 编码)XDoclet 把模板和标签处理器打包成模块不同的模块处理不同的问题域

XDoclet 生成的结构模型

XDoclet 对包含嵌入式 XDoclet 标签的输入 Java 源代码进行解析并为代码建立非常详细的结构模型结构模型中的每个元素都代表源代码中的一个 Java 结构 显示的结构模型揭示了 XDoclet 跟蹤的代码构造和关系

XDoclet 的解析的 Java 源代码的内部结构模型

中的结构模型跟蹤类接口方法之类的代码构造(模型元素)该模型还跟蹤元素之间的关系例如继承和接口实现以内联注释的形式嵌入在源代码中的 XDoclet 标签被解析为模型元素的属性并被跟蹤

通用的 Javadoc 引擎

能够理解 Java 代码结构模型的智能代码生成引擎不是什么新概念实际上它是 JDK 自带的 Javadoc 工具的运作方式通过解析带有特殊 Javadoc 标签的 Java 源文件Javadoc 工具可以为所有 Java 程序的内置结构元素(包括类接口字段和方法)生成 HTML 文档Javadoc 还具有特殊 Java 语言概念方面的知识例如继承抽象类存储类和修饰符

XDoclet 的诞生来自这样一个观察适用于任意代码生成的 Javadoc 的通用版本在许多编程场合下会极为有用但是实际的 Javadoc 源代码不是为通用的代码生成设计的而只是为了生成 HTML 文档由于无法重用现有代码XDoclet 开发小组从头开始重写了引擎并显着优化了它的性能

深入 XDoclet

显示了 XDoclet 的内部结构揭示了使其运行的功能块

XDoclet 内部的功能块

如图 所示Apache Ant 在运行的时候控制着 XDoclet 的配置和操作XDoclet 解析输入的 Java 源代码并在内存中生成结构模型模板引擎通过处理一组模板和标签处理器生成输出文件模板和标签处理器可以是内置的也可以是定制的在代码生成期间模板和标签处理器拥有对结构模型的完全访问

XDoclet 虚假的复杂性

XDoclet 实质上就是一个通用的 Javadoc 引擎(请参阅侧栏 通用的 Javadoc 引擎)那么是什么让它看起来这么复杂呢?答案在于XDoclet 几乎从未被单独讨论过而总是藏在其他许多复杂的技术中 显示了了围绕在 XDoclet 周围的复杂性迷雾(请参阅侧栏 为什么 XDoclet 看起来比实际的要复杂得多)

为什么 XDoclet 看起来比实际的要复杂得多

Apache Ant 自动进行 Java 软件的生成过程构建管理过程通常是生产项目中更复杂过程中的一部分构建管理的术语和概念被集成到 Apache Ant 中而且是理解其操作的先决条件成熟的 Ant 脚本可能会非常复杂Ant 的每个新版本都会引入一些新的特性集从而进一步增加了复杂性这形成了 XDoclet 表面的复杂性因为 XDoclet 需要 Ant 才能执行

XDoclet 处理的问题领域是复杂性的另一个来源在发布 XDoclet 的时候XDoclet 已经可以为 EJB 组件集成JEE Web 容器集成Hibernate 持久性层Struts 框架Java 管理扩展(JMX)等生成代码这些问题领域中的每一个领域都有一大套该领域专用的行话和概念从这些复杂的问题领域出来的问题经常主导着 XDoclet 的讨论这也提高了 XDoclet 表面的复杂性可能是只见森林不见树木

XDoclet 的复杂耦合

在图 您可以看到 XDoclet 与以下内容是紧密相关的

Apache Ant它控制着 XDoclet 的操作XDoclet 是作为一组 Ant 任务存在的没有 Ant 则不能执行

与生成文件关联的具体问题领域的一些细节

XDoclet 本身却是惊人地简单正如下面示例中的工作代码所示的那样

使用 XDoclet

现在您可以通过研究我向您提供的数据入口应用程序示例来观察 XDoclet 的实际工作(要下载这个示例中使用的 Java 代码XDoclet 模板和 Ant 脚本请单击本文顶部或底部的 Code图标或者请参阅 下载部分)我们将从检查清单 所示的 Java 代码开始这部分代码表示了一个客户的地址该地址被编码成 JavaBean 组件其中的 XDoclet 标签是以黑体字形式显示的

清单 用 XDoclet 标签标记的 AddressBeanjava 源文件

package comibmdwbeans;import javaioSerializable; /** * @dwgenStrutsAction action=/addAddressdo * @hibernateclass table=ADDRESS*/ public class AddressBean implements Serializable {private String streetNumber = ; private String street = ; private String city = ; private String country = ; private String postalCode = ; private long id = ; public AddressBean() { }/*** @dwgenStruts formlabel=Street Number * @hibernateproperty length=*/ public String getStreetNumber() {return streetNumber; }public void setStreetNumber(String inpStreetNumber) {streetNumber = inpStreetNumber;}/*** @dwgenStruts formlabel=Street * @hibernatepropertylength=*/ public String getStreet() { return street; }public void setStreet(String inpStreet) {street = inpStreet; } more Address bean properties /*** @hibernateid generatorclass=native*/ public long getId() { return id; }public void setId(long inId) {id = inId; }}

在清单 需要注意的是要把 XDoclet 标签嵌入到注释中紧放在相关代码元素(例如字段方法接口或类)的前面在解析源代码时XDoclet 会为每个标签建立一个属性并将该属性附加到结构模型的代码元素上现在请注意 ;@dwgenStruts 标签因为这是在本例中将用到的第一个模板

生成另外一个 Java 类

对于本例您需要生成新的 Java 类的代码 —— 一个 Struts 表单 beanStruts 会用这个 bean 保存并传输用户输入bean 必须以 bean 属性的形式包含所有数据字段而且它必须是 orgapachestrutsactionActionForm 的子类

为了生

上一篇:如何实现将统计表格保存成excel文件

下一篇:WMI中的Windows PowerShell脚本使用方法