1. Maven 的生命周期就是为了对所有的构建过程进行抽象和统一。这个生命周期包含了项目的清理、初始化、编译、测试、打包、集成测试、验证、部署和站点生成等几乎所有构建步骤。 Maven 的生命周期是抽象的,不做任何实际工作,实际任务都交由插件完成。(这种思想与 template method 非常类似)每个构建步骤可以绑定一个或者多个插件行为。 Maven 为大多数构建步骤编写并绑定了默认插件,如: maven-compiler-plugin 和 maven-surefire-plugin 。
2. M aven 拥有三套相互独立的生命周期,它们分别是: clean 、 default 和 site 。每个生命周期包含一些阶段 (phase) ,这些阶段是有顺序的,而且后面的阶段依赖于前面的阶段。用户和 Maven 最直接的交互方式是调用这些生命周期的阶段。在调用某一阶段时,该阶段所在的生命周期之前的阶段会首先被执行。但不同周期间的阶段是相互独立的。
3. clean 生命周期的目的是清理项目,它包含三个阶段: pre-clean , clean , post-clean 。
4. default 生命周期定义了真正构建时所需要执行的所有步骤,包含如下阶段 : validate , initialize , generate-soruces , process-sources , generate-resources , process-resources , compile , process-classes , generate-test-sources , process-test-sources , generate-test-resources , process-test-resources , test-compile , process-test-classes , test , prepare-package , package , pre-integration-test , integration-test , post-integration-test , verify , install , deploy 。
5. site 生命周期的目的是建立和发布站点,它包含四个阶段: pre-site , site , post-site , site-deploy 。
6. 关于生命周期的详细介绍,可以参考:
http://maven.apache.org/guides/introduction/introduction-to-the-lifecycle.html
7. 从命令行执行 Maven 任务的最主要方式就是调用 Maven 的生命周期阶段。如 mvn clean deploy site-deploy 调用了 clean 生命周期的 clean 阶段(自动触发 clean 之前的依赖: pre-clean )、 default 生命周期的 deploy 阶段(自动触发 deploy 之前的依赖)以及 site 生命周期的 site-deploy 阶段(自动触发 site-deploy 之前的依赖: pre-site , site , post-site )。
8. 插件以独立的构件形式存在, Maven 会在需要的时候下载并使用插件。
9. 一个插件可以完成多个任务(功能),每个功能就是一个插件目标( plugin goal )。如 dependency:analyze 表示插件 maven-dependency-plugin 的 analyze 目标。
10. M aven 生命周期的阶段与插件的目标相互绑定,以完成某个具体的构建任务。 Maven 的核心为一些主要的生命周期阶段默认绑定了很多插件目标,可以参考 :
查看具体的绑定关系。由于项目的打包类型会影响构建的具体过程,因此 default 生命周期的阶段与插件目标的绑定关系由项目打包类型决定。
11. 在 POM 中自定义生命周期阶段与插件目标的绑定关系:
<build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-source-plugin</artifactId> <version>2.1.1</version> <executions> <execution> <id>attach-sources</id> <phase>verify</phase> <goals> <goal>jar-no-fork</goal> </goals> </execution> </executions> </plugin> </plugins> </build>
可以将 mven-source-plugin 中的 jar-no-fork 目标(将项目的主代码打包成 jar 文件)绑定到 verify 这个 phase 。
12. 很多插件的目标在编写时已经定义了默认绑定阶段。可以用以下命令查看:
Mvn help:describe –Dplugin=org.apache.maven.plugins:maven-source-plugin:2.1.1 –Ddetail 。
13. 如果多个目标被绑定到同一个阶段,它们的执行顺序由插件声明的先后顺序决定。
默认绑定与自定义绑定的执行顺序是?
14. 可以在命令行执行 maven 命令时提供 plugin 的参数配置:
Mvn install –Dmaven.test.skip=true
maven.test.skip 是 maven-surefire-plugin 的一个参数,当其值为 true 时,就会跳过执行测试。
15. 可以在 POM 的插件配置中对插件进行一个全局的参数配置:
<build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>2.1</version> <configuration> <source>1.5</source> <target>1.5</target> </configuration> </plugin> </plugins> </build>
该配置告诉 maven-compiler-plugin 要编译的源文件是 Java 1.5 的,并且生成与 JVM 1.5 兼容的字节代码文件。由于 maven-compiler-plugin 被绑定到 compile 与 test-compile 阶段,所以上述配置对这两个阶段都会生效。
16. 我们还可以为某个插件目标及其绑定的某个阶段配置特定的参数:
<plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-antrun-plugin</artifactId> <version>1.3</version> <executions> <execution> <id>ant-validate</id> <phase>validate</phase> <goals> <goal>run</goal> </goals> <configuration> <tasks> <echo>I’m bound to validate phase.</echo> </tasks> </configuration> </execution> <execution> <id>ant-verify</id> <phase>verify</phase> <goals> <goal>run</goal> </goals> <configuration> <tasks> <echo>I’m bound to verify phase.</echo> </tasks> </configuration> </execution> </executions> </plugin>
以上配置将 maven-antrun-plugin:run 绑定到了 validate 与 verify 两个 phase ,但为两个 phase 设置了不同的参数。
17. 基本上所有的插件都来自于 Apache 和 Codehaus 。
插件来源 |
插件列表 |
下载地址 |
Apache |
||
Codehaus |
18. 可以从插件目标的文档中查阅参数的 Expression 属性,它表示了该参数在命令行中的参数名,如果没有 Expression 则说明该插件目标参数只能在 POM 中配置。如:
Maven-surefire-plugin 的 skip 参数, Expression 为 :${maven.test.skip} 则在命令行中配置该参数时参数名就为 -Dmaven.test.skip 。而在 POM 中配置时,参数名为 skip 。
19. 我们既可以通过 mvn 命令激活某个生命周期阶段,也可以直接调用某个插件目标,因为有些任务不适合绑定到生命周期阶段上,如: maven-help-plugin:describe , maven-dependency-plugin:tree 。 为了简化插件目标的定位, Maven 引入了插件前缀( Plugin Prefix ),可以用插件前缀替换插件坐标,方便在命令行直接运行插件。如:
Mvn help:describe –Dplugin=compiler –Dgoal=compile -Ddetail
20. Maven 会区别对待依赖的远程仓库和插件的远程仓库。可以在 POM 中配置插件的远程仓库。 Maven 内置的插件仓库配置:
<pluginRepositories>
<pluginRepository>
<id>central</id>
<name>Maven Plugin Repository</name>
<url>http://repo1.maven.org/maven2</url>
<layout>default</layout>
<snapshots>
<enabled>false</enabled>
</snapshosts>
<releases>
<updatePolicy>never</updatePolicy
>
</releases>
</pluginRepository>
</pluginRepositories>
一般来说,中央仓库所包含的插件完全能够满足我们的需要。
21. 配置插件时可以不配置其 groupId , Maven 会默认用 org.apache.maven.plugins 。
22. Maven 在超级 POM 中为所有核心插件定义了版本。如果用户使用某个插件而没定义版本时,会使用超级 POM 中定义的版本,如果这个插件不属于核心插件, Maven 2 会解析成 lastest 而 Maven 3 会解析成 release 。
23. 插件前缀会保存在 groupId/maven-metadata.xml 中。 Maven 在解析插件仓库元数据时,会默认使用 org.apahce.maven.plugins 和 org.codehaus.mojo 两个 groupId ,用户可以配置 settings.xml 让 Maven 检查其他 groupId 上的插件仓库元数据:
<settings> <pluginGroups> <pluginGroup>com.your.plugins</pluginGroup> </pluginGroups> </settings>
元数据信息如下:
<metadata> <plugins> <plugin> <name>Maven Clean Plugin</name> <prefix>clean</prefix> <artifactId>maven-clean-plugin</artifactId> </plugin> … </plugins> </metadata>