Ant自定义任务 Example

 作为现在Java构建工具中事实上的标准,Ant被设计成可以通过Java类进行扩展,而且只需要很少的Java代码,就可以编写一个新的Ant任务。其实编写一个 Ant任务非常简单,只需要编写一个带有一个execute()方法的Java类就行了。

package com.hsp.tasks;
public class DefAntTask{	
	public  void execute(){
		System.out.println("def Ant task....");			
	}
}

这个Java不需要扩展任何基类,只需要一个方法就行:execute( )。但这个方法必须是公有的(public),没有参数,而这个类必须能通过无参的构造函数实例化。这个方法可以有返回值,但是会被忽略并且产生一个警告信息。任务在执行过程中可以有System.out和System.err的输出,但是会被Ant截获并按照适当的日志级别输出到控制台,当然也可以配置让日志输出到文件中。

<taskdef>标签用于自定义一些任务,从而将第三方的任务集成到构建文件中。你可以在目标(<target>)之外声明<taskdef>,以便把这些任务定义成全局任务,这样在就可以像使用 Ant 的核心任务一样使用这个自定义的任务了。不过任务的类文件必须位于其可见的classpath内。为了可以在一个构建过程中使用编译过的任务,<taskdef>必须出现在编译之后。如下build.xml

<?xml version="1.0" encoding="UTF-8"?>
<!-- ====================================================================== 
     2015年3月29日 下午10:20:43                                                        

     project    
     description
                   
     gaoweigang                                                                
     ====================================================================== -->
<project name="project" default="execute">
    <description>
            description
    </description>
	<!--Ant执行日志-->
    <record name="D:/log4j.log" loglevel="info" append="no" action="start"/>
	
	<property name="build.dir" location="build"></property>
	
	<target name="init">
	    <mkdir dir="${build.dir}"/>
	</target>
    
	<target name="compile" depends="init">
		<!--编译 实现的自定义任务DefAntTask.java,生成的class文件位于${build.dir}中-->
	    <javac srcdir="src" destdir="${build.dir}" ></javac>
	</target>
	
	<target  name="execute"  depends="compile">
		<!--定义任务-->
	    <taskdef  name="DefAntTask" classname="com.hsp.tasks.DefAntTask" classpath="${build.dir}" />
		<!--调用执行自定义任务-->
		<DefAntTask/>
	</target>
	
</project>
1.1   任务的生命周期

下面是Ant任务的生命周期,构建过程从装载Ant和解析构建文件开始:

  • 当Ant 解析构建文件时,对文件中声明的每个任务,通过不带参数的构造函数建立一个恰当的Task的子类的实例。      
  • Ant传递一些信息给任务,包括任务所在的工程和目标、以及其他一些次要细节,例如它出现在构建文件中的行数。
  • Ant调用Task类的init( )函数。大多数任务都不重写这个函数。
  • Ant按照自己的方式,一次执行目标(就是依据depends属性指定的顺序) 一个目标中的任务得以逐个执行。对于每一个任务,Ant先根据构建文件的属性和元素的值对其进行配置,然后调用其execute( )函数。

Ant内部使用TaskAdapter,一个派生自org.apache.tools.ant.Task的任务适配器来处理那些不扩展Task类的任务。适配器中有个Object实例,并会调用任务对象的execute( )方法。

2.Ant API

现在我们就来了解一下Ant中主要的API,作为开发者的我们需要经常和它们打交道。

2.1 Task

抽象类org.apache.tools.ant.Task是Ant任务最常用的基类,是Ant构建过程中的主要工作单元。Task类通过保护类型成员变量project,提供对project对象的访问。还有log方法则可以将输出传给Ant进程。Task类中主要是init()和execute()方法需要重载,而log()方法(log(String msg, int msgLevel)和log(String msg))主要是用于调用,它是调用project对象的log函数。其中有五个日志级别(按优先级排列):

  • MSG_ERR
  • MSG_WARN
  • MSG_INFO
  • MSG_VERBOSE
  • MSG_DEBUG

2.2 Project

String  getProperty(String name):返回某个Ant特性的值,如果不存在这个特性,则返回null。

Void  setNewProperty(String name,  String value):给一个特性赋值,但要记住Ant中的特性是不可变更的。所以这个方法在这个特性存在的情况下,就什么都不作。

File getBaseDir():这个函数返回工程的基准目录(base directory)。它对解析相对路径非常有用,虽然在实际中用的并不多,因为Ant的文件和路径已经具有了自动展开的功能。

File resolveFile(String filename):这个函数根据文件名返回带有绝对路径的File对象。假如文件名是个相对值,则它会根据工程的基准目录进行解析。

2.3 Path

String toString():返回经过完全解析的、且平台相关的完整路径信息。

static String[]  translatePath(Project project , String path):这个工具函数根据某个路径分解得到路径元素数组,那个路径包含着由冒号或者分号分隔开来的路径元素。

int size():返回Path实例中路径元素的数量。

String[] list():返回Path实例中路径元素数组。

2.4 Fileset

2.5 DirectoryScanner

2.6 EnumeratedAttribute

2.7 FileUtils

3.属性

XML属性其实就是一个名值对。假如你现在有一个 任务,仅有一个属性name:

       <DefAntTask  name=”gaoweigang”/>

这个任务有个setName的函数:

       private  String  name;

       public  void  setName(String  name) {

              this.name = name;

       }

这和JavaBean的命名风格很相似,每个特性都对应一个读写器(setter/getter)。属性的内省机制支持Java的基本类型和包装类型,而类型之间的转换出现错误的话,将抛出NumberFormatException异常,构建过程将停止。

通过实现一个以java.io.File参数的设值函数,Ant提供了对文件或者目录属性内置的支持,它可以将构建文件中的相对目录解析为绝对路径。

<DefAntTask  destdir =”descFile”/>

对应的任务就实现了setDestDir函数:

private  File  destFile;

public  void  setDestDir(File  destFile) {

       this.destFile  =  destFile;

}

例如:工程目录结构如下:


 

①实现自定义任务

package com.hsp.tasks;

import java.io.File;

public class DefAntTask{
	
	private String name;
	
	private String password;
	
	private File destfile;
	
	public  void execute(){
		System.out.println("def Ant task....");
		
		System.out.println("name:"+name);
		System.out.println("password:"+password);
		
		System.out.println(destfile.getAbsolutePath());
				
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public String getPassword() {
		return password;
	}

	public void setPassword(String password) {
		this.password = password;
	}

	public File getDestfile() {
		return destfile;
	}

	public void setDestfile(File destfile) {
		this.destfile = destfile;
	}


}

②在build.xml使用自定义任务

<?xml version="1.0" encoding="UTF-8"?>
<!-- ====================================================================== 
     2015年3月29日 下午10:20:43                                                        

     project    
     description
                   
     gaoweigang                                                                
     ====================================================================== -->
<project name="project" default="execute">
    <description>
            description
    </description>
	<!--Ant执行日志-->
    <record name="D:/log4j.log" loglevel="info" append="no" action="start"/>
	
	<property name="build.dir" location="build"></property>
	
	<target name="init">
	    <mkdir dir="${build.dir}"/>
	</target>
    
	<target name="compile" depends="init">
		<!--编译 实现的自定义任务DefAntTask.java,生成的class文件位于${build.dir}中-->
	    <javac srcdir="src" destdir="${build.dir}" ></javac>
	</target>
	
	<target  name="execute"  depends="compile">
		<!--定义任务-->
	    <taskdef  name="DefAntTask" classname="com.hsp.tasks.DefAntTask" classpath="${build.dir}" />
		<!--调用执行自定义任务,并且向任务类传递属性-->
		<DefAntTask name="gaoweigang" password="123456" destfile="./src"/>
	</target>
	
</project>

 ③执行构建,日志输出如下:


 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

<?xml version="1.0" encoding="UTF-8"?>

<project basedir="." default="builddatabase">

<!-- ================================================================== -->

<!-- 其他配置 -->

<!-- ================================================================== -->

<property file="build_database.properties" />

<path id="toolslib">

<!--定义java编译结果.class文件的跟目录 -->

<pathelement location="${depend_classes_folder}" />

<!-- 需要使用的第三方jar存放目录 -->

<fileset dir="${depend_libs_folder}">

<include name="**/*.jar" />

</fileset>

</path>

<target name="builddatabase">

<taskdef name="buildToolTask" classname="com.ling2.build.ant.BuildToolTask"

classpathref="toolslib" />

<!-- destdir属性可以在各输出属性中分别指定,这里是全局指定 -->

<buildToolTask database_configfile="${database_configfile}"

config_rootfolder="${config_rootfolder}" errolist_configfile="${errolist_configfile}"

svn_rootfolder="${depend_svn_rootfolder}" result_rootfolder="${depend_result_rootfolder}"

publish_filename="${publish_filename}" database_name="${database_name}">

<hkTask />

</buildToolTask>

</target>

 

</project>

 

参考:http://blog.csdn.net/jackkp_catus/article/details/2295612

猜你喜欢

转载自weigang-gao.iteye.com/blog/2190774
今日推荐