AntCall 任务的作用是允许在一个target的执行过程中调用并执行其他的target。例如,在打包项目前需要对项目进行编译,那么可以在打包项目的target中通过AntCall任务使得编译的target先执行。当然这种情况也可以通过target间设置depends属性来实现。AntCall任务必须在target元素内执行,这个任务不能在target元素外执行。
1. AntCall Task属性及功能
AntCall 任务主要包括target,inheritAll和inheritRefs 3个属性,具体说明如下:
(1)target属性:在AntCall任务中target属性的作用是指定要被调用执行的target,通过名称指定这个target属性是必需的。值得注意的是,当通过AntCall任务调用的target存在依赖的target(depends中指定了target),则depends属性中被指定的target也会被执行。
(2)inheritAll属性:用于指定是否继承当前的属性。默认时为true,代表被调用的target可使用这些属性。
(3)inheritRefs属性:用于指定是否覆盖reference属性或者是否建立一个对当前reference属性的引用。在默认的情况下,AntCall任务不会覆盖reference属性,除非把inheritRefs属性设为true。默认时inheritRefs属性为false。
2. 利用AntCall Task实现target间调用的实例
利用AntCall任务来实现target间的相互调用。下面编写构件文件antcallSample.xml,实现在targetA中调用执行targetB。构件文件内容如下:
<?xml version="1.0"?>
<project name="antcallSample" default="targetA">
<target name="targetA">
<echo message="In targetA calling targetB"/>
<!-- //调用targetB -->
<antcall target="targetB" >
</antcall>
<echo message="After call targetB" />
</target>
<target name="targetB" >
<echo message="In targetB" />
</target>
</project>
保存构件文件,然后在命令行执行命令ant –f antcallSample.xml,执行结果如图所示。
antcallSample.xml
上面的例子的作用是在执行targetA的过程中执行targetB。如果targetB中设定了depends属性,则depends属性中指定的target也会被执行。修改antcallSample.xml如下,以演示depends的依赖关系:
<?xml version="1.0"?>
<project name="antcallSample" default="targetA">
<target name="init" >
<echo message="In init target"/>
</target>
<target name="targetA">
<echo message="In targetA calling targetB"/>
<antcall target="targetB" >
</antcall>
<echo message="After call targetB" />
</target>
<target name="targetB" depends="init">
<echo message="In targetB" />
</target>
</project>
保存构件文件,然后再次执行ant –f antcallSample.xml命令,执行结果如图所示。
antcallSample.xml命令的执行结果
上面的执行结果表明:在执行targetA时调用targetB,由于targetB依赖于init target。因此init target先于targetB执行。
3. 利用AntCall Task实现target间调用时传递参数的实例
当需要从一个target传递参数到被调用的target时,可以使用<param> 类型进行传递。当然也可以在target中定义property来实现,与Java中的方法调用时传递参数相似。修改antcallSample.xml以实现传递参数的功能,内容如下:
<?xml version="1.0"?>
<project name="antcallSample" default="targetA">
<target name="init" >
<echo message="In init target"/>
</target>
<target name="targetA">
<echo message="In targetA calling targetB"/>
<!-- //通过property传递 -->
<property name="prop" value="prop property" />
<antcall target="targetB" >
<!-- // 通过antcall设定param实现 -->
<param name="path1" value="path1 param" />
</antcall>
<echo message="After call targetB" />
</target>
<target name="targetB" depends="init">
<echo message="In targetB" />
<echo message="path1=${path1}" />
<echo message="prop=${prop}" />
</target>
</project>
再次执行ant –f antcallSample.xml命令,执行结果如图所示。
antcallSample.xml
从执行结果可看出,通过property指定和通过AntCall中的param指定的属性都传递到targetB中。对于param 类型只有两个属性:name和value。由于AntCall任务中的inheritAll属性默认时为true,所以property能被targetB引用。如果targetB中也定义了相同的property,那么可以通过设置inheritRefs属性和reference类型进行覆盖。
4. depends的任务调用和antcall任务调用的细微差别
区别在于,用depends的方式调用,那么被调用任务中的设置或者修改的属性值可以在后面的任务中使用,而用antcall的调用就不可以。
在使用ant的时候,有时用
<echo>A: ${war.name}</echo>
</target>
有时用
<antcall target="war.name"/>
<echo>B: ${war.name}</echo>
</target>
<target name="war.name">
<echo>
task war.name need to pass 4 parameters:
project.name
release.version
deploy.type
</echo>
<property name="war.name" value="${project.name}-${release.version}_${deploy.type}-${today}-${build.number}.war"/>
<property name="war.file" value="${bin.dir}/${war.name}"/>
<property name="war.md5.name" value="${war.name}.MD5"/>
<property name="war.md5.file" value="${bin.dir}/${war.md5.name}"/>
<echo>
|-------------------------------------------------------------------------------|
war.name : ${war.name}
war.file : ${war.file}
war.md5.name : ${war.md5.name}
war.md5.file : ${war.md5.file}
|-------------------------------------------------------------------------------|
</echo>
</target>
那么第一种调用方法,就能正确取得war.name属性的值,而第二种调用就不能。所以建议尽可能的使用depends进行任务调用。