上一篇《maven的POM结构》让人晦涩难懂,一看就是拷贝粘贴的,很没意思。突然想起了《maven的安装使用》,估计看完总有个问题,那个maven genapp里面genapp是怎么回事?你怎么知道后面跟genapp,而不是genBush,genBullshit?先看看maven都支持什么命令行参数,输入maven -h,我们可以看到有一行如下:
-g,--goals Display available goals
我们如法炮制,输入maven -g。救命啊,屏幕发了疯的滚屏,一气输出了725行,(如果对这些输出感兴趣,建议你把它输出到文件中仔细观摩,使用命令“maven -g>文件路径”输出到目标文件,然后使用文本编辑器打开就可以了)但是这些输出都是什么呀?
我们看看前八行的输出
1 __ __
2 | \/ |__ _Apache__ ___
3 | |\/| / _` \ V / -_) ' \ ~ intelligent projects ~
4 |_| |_\__,_|\_/\___|_||_| v. 1.0
5
6 Available [Plugins] / Goals
7 ===========================
8 genapp ......................... Generate Application based on a template
9 ... ...
原来这个genapp是一个叫做goal的东西,不是“进球”的意思。指的是maven能够执行的任务,虽然名字听起来很有噱头,其实跟Ant里面的Task差不多,而且maven的goal定义里面也可以使用Ant里面的Task定义,就是诸如delete,mkdir,echo之类的Ant的Task,maven也可以照单全收,直接使用。从刚才maven -g我们可以看到maven支持如此众多的goal,也就是说已经替我们定制了一大堆门类齐全的goal供我们使用,甚至包括对JBuilder,Eclipse这样IDE的支持,可以生成它们特定的工程格式。所以maven支持的参数除了预定义的(可以用-h查看)还有就是定义好的goal。
这些goal的定义都在maven的plugins目录里面,我们看到一大堆名字怪诞的jar文件,我们随便
找一个撬开一看,里面一般的文件结构如下:
|--<META-INF>
|--plugin.jelly
|--plugin.properties
|--project.properties
|--project.xml
|--...
其实四个文件里面,只有plugin.jelly和project.xml是必须具备的,最后的省略号是说有的plugin里面还要有相关支持类包或者资源包,资源包通常叫做plugin-resources。这个jelly是Apache的一个项目(怎么又冒出来一个?),不过我们就把它当作普通的xml文件看待就可以了,除非要自制插件,否则很少接触。
有了这么强大的支持,就像编程有了强大丰富的库支持一样,我们可以省心省力了,但是如果我们觉得这些还不够用,或者我们要加点小花样怎么办?
首先要想到的就是----对了,去网上找,找符合要求的插件,SourceForge网站上还专门有一个的 Maven插件的项目,还有maven的主页的插件列表,都是提供插件资源的地方。
如果还是找不到,那就要考虑扩展已有的goal或者自定义goal。在工程文件夹定义一个文件maven.xml,这个文件是专门用来自定义goal的,所以一般工程可以没有这个文件。
文件大致框架如下:
<project xmlns:j="jelly:core">
...
<goal name=...>
...
</goal>
...
<preGoal name=...>
...
</preGoal>
<postGoal name=...>
...
</postGoal>
</project>
注意:文件头部不用<?xml version="1.0" encoding="ISO-8859-1"?>这样的声明。
<goal>标签是用来自定义goal的,扩展goal用<preGoal>和<postGoal>标签,从名字上就可以看出来,<preGoal>要定义 <preGoal name=...>中的name指定的goal在执行前要做的动作。而<postGoal>则是定义相应goal执行后要做的动作。
我们现在就来试试。我们创建一个工程,然后创建一个maven.xml文件,在文件里面添加如下内容:
<project xmlns:j="jelly:core">
<preGoal name="java:compile">
<echo>start compile</echo>
</preGoal>
<postGoal name="java:compile">
<echo>end compile</echo>
</postGoal>
</project>
java:compile是maven预定义好的goal,我们所作的是在执行它之前和之后在控制台echo出两行文字,我们在控制台上进入工程目录,敲maven java:compile,就可以看到如下内容
1 __ __
2 | \/ |__ _Apache__ ___
3 | |\/| / _` \ V / -_) ' \ ~ intelligent projects ~
4 |_| |_\__,_|\_/\___|_||_| v. 1.0
5
6 build:start:
7
8 java:prepare-filesystem:
9 [mkdir] Created dir: D:\test\maventest4\target\classes
10 java:compile:
11 [echo] start compile
12 [echo] Compiling to D:\test\maventest4/target/classes
13 [javac] Compiling 1 source file to D:\test\maventest4\target\classes
14 [echo] end compile
15 BUILD SUCCESSFUL
16 Total time: 10 seconds
17 Finished at: Wed Nov 17 12:34:23 CST 2004
11行和14行就是我们定义的结果。如果还嫌不够,可以自定义goal,如果你也定义一个跟已定义的重名的goal,那么当前工程会以你的定义为准,比如我们就拿java:compile来开刀,在maven.xml里面加上一句
<goal name="java:compile">
<echo>my java:compile do nothing but echo a sentence</echo>
</goal>
那么maven java:compile就会输出:
1 __ __
2 | \/ |__ _Apache__ ___
3 | |\/| / _` \ V / -_) ' \ ~ intelligent projects ~
4 |_| |_\__,_|\_/\___|_||_| v. 1.0
5 build:start:
6 java:compile:
7 [echo] my java:compile do nothing but echo a sentence
8 BUILD SUCCESSFUL
9 Total time: 7 seconds
10 Finished at: Wed Nov 17 12:52:30 CST 2004
如果要是在项目之间共享自定义的goal,除了把maven.xml拷来拷去,你也可以自定义自己的plugin放到maven目录里面。当然也可以发布到网上给别人使用,让更多人对你肃然起敬。具体的开发过程我还没有仔细看过,如果有什么心得,可以跟我交流。