1.基本命令
mvn site 构建一个项目站点
mvn package 打包
mvn help:effective-pom 查看有效的pom文件。由于POM可以从其它POM继承配置,你就需要一直考虑超级POM,再加上任何父POM,以及最后当前项目的POM这些所有配置的结合.。如果一个POM没有通过parent元素指定一个直接的父项目,那这个POM就会从超级POM继承值.
2.属性引用
<project>
<modelVersion>4.0.0</modelVersion>
<groupId>org.sonatype.mavenbook</groupId>
<artifactId>project-a</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>jar</packaging>
<build>
<finalName>org.sonatype.mavenbook-content-zh</finalName>
</build>
</project>
a.属性引用例子:org.sonatype.mavenbook-${project. groupId }。
b.${settings.offline}会引用~/.m2/settings.xml文件中offline元素的值。
c.。如果你在pom.xml中设置了一个名为fooBar的属性,该属性就可以通过${fooBar}引用,在POM中设置${foo}=bar的语法:
<properties>
<foo>bar</foo>
</properties>
3.依赖范围
<dependency>
<scope></scope>
</dependency>
a. compile(编译范围)
compile是默认的范围;如果没有提供一个范围,那该依赖的范围就是编译范围。编译范围依赖在所有的classpath中可用,同时它们也会被打包
b.provided(已提供范围)
provided依赖只有在当JDK或者一个容器已提供该依赖之后才使用。例如,如果你开发了一个web应用,你可能在编译classpath中需要可用的Servlet API来编译一个servlet,但是你不会想要在打包好的WAR中包含这个Servlet API;这个Servlet API JAR由你的应用服务器或者servlet容器提供。已提供范围的依赖在编译classpath(不是运行时)可用。它们不是传递性的,也不会被打包。
c.runtime(运行时范围)
runtime依赖在运行和测试系统的时候需要,但在编译的时候不需要。比如,你可能在编译的时候只需要JDBC API JAR,而只有在运行的时候才需要JDBC驱动实现。
d.test(测试范围)
test范围依赖 在一般的 编译和运行时都不需要,它们只有在测试编译和测试运
行阶段可用。测试范围依赖在之前的???中介绍过。
e.system(系统范围)
system范围依赖与provided类似,但是你必须显式的提供一个对于本地系统中
JAR文件的路径。这么做是为了允许基于本地对象编译,而这些对象是系统类库
的一部分。这样的构件应该是一直可用的,Maven也不会在仓库中去寻找它。如
果你将一个依赖范围设置成系统范围,你必须同时提供一个systemPath元素。注
意该范围是不推荐使用的(你应该一直尽量去从公共或定制的Maven仓库中引用
依赖)。
4.排除一个传递性依赖
以下列举了一些你可能想要排除或者替换传递性依赖的情况:
a. 构建的groupId和artifactId已经更改了,而当前的项目需要一个与传递性依赖不同名称的版本——结果是classpath中出现了同样项目的两份内容。一般来说Maven会捕捉到这种冲突并且使用该项目的一个单独的版本,但是当artifactId和artifactId不一样的时候,Maven就会认为它们是两种不同的类库。
b. 某个构件没有在你的项目中被使用,而且该传递性依赖没有被标志为可选依赖。在这种情况下,你可能想要排除这种依赖,因为它不是你的系统需要的东西,你要尽量减少应用程序分发时的类库数目。
c. 一个构件已经在运行时的容器中提供了,因此不应该被包含在你的构件中。该情况的一个例子是,如果一个依赖依赖于如Servlet API的东西,并且你又要确保这样的依赖没有包含在web应用的WEB-INF/lib目录中。
d. 为了排除一个可能是多个实现的API的依赖。这种情况在例 9.8 “排除并替换一个传递性依赖”中阐述;有一个Sun API,需要点击许可证,并且需要耗时的手工安装到自定义仓库,对于同样的API有可免费分发版本,在中央Maven仓库中可
用(Geronimo's JTA 实现)。
<dependency>
<groupId>org.sonatype.mavenbook</groupId>
<artifactId>project-a</artifactId>
<version>1.0</version>
<exclusions>
<exclusion>
<groupId>org.sonatype.mavenbook</groupId>
<artifactId>project-b</artifactId>
</exclusion>
</exclusions>
</dependency>
使用pom.xml中的dependencyManagement元素能让你在子项目中引用一个依赖而不用显式的列出版本号。Maven会沿着父子层次向上走,直到找到一个拥有dependencyManagement元素的项目,然后它就会使用在这个dependencyManagement元素中指定的版本号。
<dependencyManagement>
<dependencies>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.2</version>
</dependency>
...
<dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.2</version>
</dependency>
...
<dependencies>
</dependencyManagement>
然后在子项目中不用写版本号
<dependencies>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
</dependencies>
6.坐标详解
groupId
一个groupId归类了一组相关的构件。组定义符基本上类似于一个Java包名。例如:groupId org.apache.maven是所有由Apache Maven项目生成的构件的基本groupId。组定义符在Maven仓库中被翻译成路径,例如,groupIdorg.apache.maven可以在repo1.maven.org1的/maven2/org/apache/maven目录下找到。
artifactId
artifactId是项目的主要定义符。当你生成一个构件,这个构件将由artifactId命名。当你引用一个项目,你就需要使用artifactId来引用它。artifactId和groupId的组合必须是唯一的。换句话说,你不能有两个不同的项目拥有同样的artifactId和groupId;在某个特定的groupId下,artifactId也必须是唯一的。
注意
虽然‘.’在groupId中很常用,而你应该避免在artifactId中使用
它。因为在解析一个完整限定名字至子模块的时候,这会引发问题。
version
当一个构件发布的时候,它是使用一个版本号发布的。该版本号是一个数字定义符如“1.0”,“1.1.1”,或“1.1.2-alpha-01”。你也可以使用所谓的快照(snapshot)版本。一个快照版是一个处于开发过程中的组件的版本,快照版本号通常以SNAPSHOT结尾;如,“1.0-SNAPSHOT”,“1.1.1-SNAPSHOT”,和“1-SNAPSHOT”
7.多模块项目
<project>
<groupId>org.sonatype.mavenbook</groupId>
<artifactId>top-group</artifactId>
...
<modules>
<module>sub-group</module>
<module>project-c</module>
</modules>
...
</project>
<groupId>org.sonatype.mavenbook</groupId>
<artifactId>top-group</artifactId>
...
<modules>
<module>sub-group</module>
<module>project-c</module>
</modules>
...
</project>
当Maven读取top-group的POM的时候,它会检查它的modules元素,看到top-group引用了项目sub-group和project-c。之后Maven会在它们的每个子目录中寻找pom.xml.