本文来自:http://www.ibm.com/developerworks/cn/java/j-lo-antstructure/
引言
Ant 脚本是由 Apache 提供的一种基于 Java 的构建工具,为 Java 开发人员所熟悉。Java 开发人员使用 Ant 脚本可以很方便地完成 Java 开发过程中常见的如拷贝文件、创建目录、编译、打包、压缩文件等等重复性的工作,从而提高开发效率,减轻开发人员负担,达到提高开发质量的目的。
Ant 既然是一种脚本语言,那么如何才能结构化设计 Ant 脚本, 从而使 Ant 脚本更易维护、更易扩展、更易重用,本文将就此目的做一些探讨。
使用Ant generic target
在 Ant 中有 target(目标)和 task(任务)两个概念,一个 target 是 task 的容器,它可以包含一个或者多个任务,它们之间是一对多的关系。任务的例子有拷贝文件、创建目录等等。
在日常的开发过程中,经常会有一些经常重复的事情,对于这些事情我们可以定义一个 target 作为一个通用的 target,即 generic target, 它带有一些参数,这些参数由调用者在调用这个 generic target 时给定。别的 target 可以使用 antcall 任务去调用这个 generic target, 从而达到重用的目的。我们来看一个例子 , 比如说,调用一个 SQL 脚本文件,那么我们可以按照清单 1 构造一个 generic target:
清单一
|
对于这个 Ant generic target run.sqlscript
我们看到它有下列参数:driver.name
,jdbc.url
, user.name
,user.password 及 sql.source
,driver.name
指 JDBC 数据库驱动类的名字,例如对于 Oracle 数据库来说它叫oracle.jdbc.driver.OracleDriver
,jdbc.url
是要连接的数据库的 URL,例如 jdbc:oracle:thin:@9.186.12.11:1521:XE,user.name
和user.password
分别是用户登陆名和密码,sql.source
是要调用的 SQL 脚本,<classpath refid="deployment.lib" />
定义的类路径中包含对应数据库的 JDBC 驱动类包 , 请您参考清单 5。
那么如果要从一个 target 中调用这个 generic target, 那么我们可以按照清单 2 给出的例子来做:
清单二
<target name="call.database">
<antcall target="run.sqlscript">
<param name="driver.name" value=" oracle.jdbc.driver.OracleDriver"/>
<param name="jdbc.url" value=" jdbc:oracle:thin:@9.186.12.11:1521:XE"/>
<param name="user.name" value="test" />
<param name="user.password" value="test"/>
<param name="sql.source" value="${basedir}/../prj/oracle.sql" />
</antcall>
</target>
|
下面再看一个例子,例如我们要输出一条消息及这条消息输出时的时间,时间的格式可以按照用户的需求设定,那么我们可以按照清单 3 给出的例子写一个 generic target echo.time:
清单三
|
这个 generic target echo.time 有三个参数,time.pattern,locale 和 message
.time.pattern 指的是时间格式,如时间格式 yyyy/MM/dd hh:mm:ss:SS aa
,locale 即区域及语言设置,如 zh,CN,即中国中文,message 即是用户要输出的消息。
我们可以按照清单 4 中的例子调用这个 generic target echo.time。
清单四
|
组织Ant generic target
在使用 Ant generic targets 这个章节中演示两个例子后,我们来看如何组织这些 generic targets。 在面向对象的教程中经常会提到松耦合和内聚,松耦合即模块之间要减少依赖,内聚即实现类似功能的代码要放在一个模块中。按照这个原则我们可以把 generic targetrun.sqlscript
放在一个叫 Database.xml 的 XML 文件中,把 generic target echo.time
放在一个叫Util.xml
的 XML
文件中 , 如清单 5 和 6 所示:
清单五
|
清单六
|
在这两个文件 Database.xml 和 Util.xml
中,您可能注意到都有以dirname
开头用黑体标注的一行 , 这一行非常重要,它定义了一个 property proj.basedir
,property proj.basedir
是用来储存Database.xml 和 Util.xm
l 两文件所处的路径,从而使它们不用依赖于调用者就能够确定自己的所处的路径,进而消除和调用者之间的耦合。
那么如何调用在这两个文件中的 generic targets 呢?我们来看一个例子,假设我们把 Database.xml 和 Util.xml
放在目录 Scripts
下 , 那么整个结构如图 1 所示:
图一
在 Build.xml
中我们需要导入文件 Database.xml 和 Util.xml
,这样就可以在Build.xml 里调用
generic targets run.sqlscript 和 echo.time 了
, 请参考清单 7。
清单七
|
总结
通过这样对 Ant 脚本的结构化设计,我们可以看出整个架构清晰,减少了耦合性,使得代码容易理解和维护,从而提高了重用性及开发效率。