3.5. 核心概念

我们已经第一次运行了Maven,是时候介绍一些Maven的核心概念了。在之前的例子中,我们生了一个项目,它包含了一个POM和一些源代码,它们一起组成了Maven的标准目录布局。之后你用生命周期阶段(phase)作为参数来运行Maven,这个阶段会提示Maven运行一系列Maven插件的目标。最后,你把Maven构件(artifact)安装(install)到了你本地仓库(repository)。等等?什么是生命周期?什么是“本地仓库”?下面的小结阐述了一些Maven的核心概念。

3.5.1. Maven插件和目标 (Plugins and Goals)

在前面一节中,我们用两种类型的命令行参数运行了Maven。第一条命令是一条单个的插件目标,Archetype插件的create目标。Maven第二次运行是一个生命周期阶段 –install。为了运行单个的Maven插件目标,我们使用mvn archetype:create这样的语法,这里archetype是一个插件标识而create是目标标识。当Maven运行一个插件目标,它向标准输出打印出插件标识和目标标识:

$ mvn archetype:create -DgroupId=org.sonatype.mavenbook.ch03 \
                                        -DartifactId=simple \
                                        -DpackageName=org.sonatype.mavenbook
...
[INFO] [archetype:create]
[INFO] artifact org.apache.maven.archetypes:maven-archetype-quickstart: \
       checking for updates from central
...

一个Maven插件是一个单个或者多个目标的集合。Maven插件的例子有一些简单但核心的插件,像Jar插件,它包含了一组创建JAR文件的目标,Compiler插件,它包含了一组编译源代码和测试代码的目标,或者Surefire插件,它包含一组运行单元测试和生成测试报告的目标。而其它的,更有专门的插件包括:Hibernate3插件,用来集成流行的持久化框架Hibernate,JRuby插件,它让你能够让运行ruby称为Maven构建的一部分或者用Ruby来编写Maven插件。Maven也提供了自定义插件的能力。一个定制的插件可以用Java编写,或者用一些其它的语言如Ant,Groovy,beanshell和之前提到的Ruby。

一个插件包含一些目标

Figure 3.1. 一个插件包含一些目标


一个目标是一个明确的任务,它可以作为单独的目标运行,或者作为一个大的构建的一部分和其它目标一起运行。一个目标是Maven中的一个“工作单元(unit of work)”。目标的例子包括Compiler插件中的compile目标,它用来编译项目中的所有源文件,或者Surefire插件中的test目标,用来运行单元测试。目标通过配置属性进行配置,以用来定制行为。例如,Compiler插件的compile目标定义了一组配置参数,它们允许你设置目标JDK版本或者选择是否用编译优化。在之前的例子中,我们通过命令行参数-DgroupId=org.sonatype.mavenbook.ch03-DartifactId=simple向Archetype插件的create目标传入了groupIdartifactId配置参数。我们也向create目标传入了packageName参数,它的值为org.sonatype.mavenbook。如果我们忽略了packageName参数,那么包名的默认值为org.sonatype.mavenbook.ch03

Note

当提到一个插件目标的时候,我们常常用速记符号:pluginId:goalId。例如,当提到Archetype插件的create目标的时候,我们写成archetype:create

目标定义了一些参数,这些参数可以定义一些明智的默认值。在archetype:create这个例子中,我们并没有在命令行中指定这个目标创建什么类型的archetype,我们简单的传入一个groupId和一个artifactId。这是我们对于约定优于配置(convention over configuration)的第一笔。这里create目标的约定,或者默认值,是创建一个简单的项目,叫做Quickstart。create目标定义了一个配置属性archetypeArtifactId,它有一个默认值为maven-archetype-quickstart。Quickstart archetype生成了一个最小项目的躯壳,包括一个POM和一个类。Archetype插件比第一个例子中的样子强大得多,但是这是一个快速开始新项目的不错的方法。在本书的后面,我们将会让你看到Archetype插件可以用来生成复杂如web应用的项目,以及你如何能够使用Archetype插件来定义你自己项目的集合。

Maven的核心对你项目构建中特定的任务几乎毫无所知。就它本身来说,Maven不知道如何编译你的代码,它甚至不知道如何制作一个JAR文件,它把所有这些任务代理给了Maven插件,像Compiler插件和Jar插件,它们在需要的时候被下载下来并且定时的从Maven中央仓库更新。当你下载Maven的时候,你得到的是一个包含了基本躯壳的Maven核心,它知道如何解析命令行,管理classpath,解析POM文件,在需要的时候下载Maven插件。通过保持Compiler插件和Maven核心分离,并且提供更新机制,用户很容易能使用编译器最新的版本。通过这种方式,Maven插件提供了通用构建逻辑的全局重用性,有不会在构建周期中定义编译任务,有使用了所有Maven用户共享的Compiler插件。如果有个对Compiler插件的改进,每个使用Maven的项目可以立刻从这种变化中得到好处。(并且,如果你不喜欢这个Compiler插件,你可以用你的实现来覆盖它)。