maven-2 一个简单的例子

目标:对构建生命周期 (build lifecycle),Maven仓库 (repositories),依赖管理 (dependency management)和项目对象模型 (Project Object Model)有一个基本的理解。

开始一个新的Maven项目,在命令行使用Maven Archetype插件。

mvn archetype:create -DgroupId=org.sonatype.mavenbook.ch03 -DartifactId=simple  -DpackageName=org.sonatype.mavenbook

我们已经生成了一个项目,看一下Maven在simple目录下创建的目录结构

simple/
simple/pom.xml
      /src/
      /src/main/
      /main/java
      /src/test/
      /test/java
  1. 这个生成的目录遵循Maven标准目录布局,我们之后会去看更多的细节,但是,现在让我们只是尝试了解这些基本的目录Maven Archtype插件创建了一个与 artifactId 匹配的目录——simple。这是项目的基础目录。
  2. 每个项目在文件 pom.xml 里有它的项目对象模型 (POM)。这个文件描述了这个项目,配置了插件,声明了依赖。
  3. 我们项目的源码了资源文件被放在了 src/main 目录下面。在我们简单Java项目这样的情况下,这个目录包含了一下java类和一些配置文件。在其它的项目中,它可能是web应用的文档根目录,或者还放一些应用服务器的配置文件。在一个Java项目中,Java类放在 src/main/java 下面,而classpath资源文件放在 src/main/resources 下面。
  4. 我们项目的测试用例放在 src/test 下。在这个目录下面, src/test/java 存放像使用JUnit或者TestNG这样的Java测试类。目录 src/test/resources 下存放测试classpath资源文件。

想要构建打包这个应用,在包含 pom.xml 的目录下运行mvn install。

已经创建了,编译了,测试了,打包了,并且安装了(installed)最简单的Maven项目。在命令行运行它以向你自己验证这个程序能工作。

java -cp target/simple-1.0-SNAPSHOT.jar org.sonatype.mavenbook.App

简单的项目对象模型 (Project Object Model)

当Maven运行的时候它向项目对象模型(POM)查看关于这个项目的信息。POM回答类似这样的问题:这个项目是什么类型的?这个项目的名称是什么?这个项目的构建有自定义么?这里是一个由Maven Archetype插件的create目标创建的默认的 pom.xml 文件。

<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.sonatype.mavenbook.ch03</groupId>
<artifactId>simple</artifactId>
<packaging>jar</packaging>
<version>1.0-SNAPSHOT</version>
<name>simple</name>
<url>http://maven.apache.org</url>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>
</dependencies>
</project>

这个 pom.xml 文件是你将会面对的Maven项目中最基础的POM,一般来说一个POM文件会复杂得多:定义多个依赖,自定义插件行为。最开始的几个元素—— groupId , artifactId ,  packaging ,  version ——是Maven的坐标(coordinates),它们唯一标识了一个项目。 name 和 url 是POM提供的描述性元素,它们给人提供了可阅读的名字,将一个项目关联到了项目web站点。最后,dependencies元素定义了一个单独的,测试范围(test-scoped)依赖,依赖于称为JUnit的单元测试框架.

当Maven运行的时候,它是根据项目的 pom.xml 里设置的组合来运行的,一个最上级的POM定义了Maven的安装目录,在这个目录中全局的默认值被定义了,(可能)还有一些用户定义的设置。想要看这个“有效的 (effective)”POM,或者说Maven真正运行根据的POM,在simple项目的基础目录下跑下面的命令。 mvn help:effective-pom

核心概念

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

一个Maven插件是一个单个或者多个目标的集合。一个目标是一个明确的任务,它可以作为单独的目标运行,或者作为一个大的构建的一部分和其它目标一起运行。一个目标是Maven中的一个“工作单元(unit of work)”。目标的例子包括Compiler插件中的 compile 目标,它用来编译项目中的所有源文件,或者Surefire插件中的 test 目标,用来运行单元测试。目标通过配置属性进行配置,以用来定制行为。

目标定义了一些参数,这些参数可以定义一些明智的默认值。在 archetype:create 这个例子中,我们并没有在命令行中指定这个目标创建什么类型的archetype,我们简单的传入一个 groupId 和一个 artifactId 。这是我们对于约定优于配置(convention over
configuration)的第一笔。这里 create 目标的约定,或者默认值,是创建一个简单的项目,叫做Quickstart.

Maven的核心对你项目构建中特定的任务几乎毫无所知。就它本身来说,Maven不知道如何编译你的代码,它甚至不知道如何制作一个JAR文件,它把所有这些任务代理给了Maven插件,像Compiler插件和Jar插件,它们在需要的时候被下载下来并且定时的从Maven中央仓库更新.

2.Maven生命周期 (Lifecycle)

我们运行的第二个命令是mvn package。命令行并没有指定一个插件目标,而是指定了一个Maven生命周期阶段。一个阶段是在被Maven称为“构建生命周期”中的一个步骤。生命周期是包含在一个项目构建中的一系列有序的阶段。Maven可以支持许多不同的生命周期,但是最常用的生命周期是默认的Maven生命周期,这个生命周期中一开始的一个阶段是验证项目的基本完整性,最后的一个阶段是把一个项目发布成产品。

生命周期的阶段被特地留得含糊,单独的定义为验证(validation),测试(testing),或者发布(deployment),而他们对不同项目来说意味着不同的事情。例如,打包(package)这个阶段在一个项目里生成一个JAR,它也就意味着“将一个项目打成一个jar”,而在另外一个项目里,打包这个阶段可能生成一个WAR文件。

“一个生命周期是一些阶段的序列”.

插件目标可以附着在生命周期阶段上。随着Maven沿着生命周期的阶段移动,它会执行附着在特定阶段上的目标。每个阶段可能绑定了零个或者多个目标。在之前的小节里,当你运行mvn package,你可能已经注意到了不止一个目标被执行了。检查运行mvnpackage之后的输出,会注意到那些被运行的各种目标。当这个简单例子到达 package 阶段的时候,它运行了Jar插件的jar目标。既然我们的简单的quickstart项目(默认)是 jar 包类型, jar:jar 目标被就绑定到了打包阶段。

Maven执行一个阶段的时候,它首先会有序的执行前面的所有阶段,到命令行指定的那个阶段为止。每个阶段对应了零个或
者多个目标。我们没有进行任何插件配置或者定制,所以这个例子绑定了一组标准插件的目标到默认的生命周期。当Maven经过以 package 为结尾的默认生命周期的时候,下面的目标按顺序被执行:

resources:resources
Resources插件的 resources 目标绑定到了 resources 阶段。这个目标复制 src/main/resources 下的所有资源和其它任何配置的资源目录,到输出目录。

compiler:compile
Compiler插件的 compile 目标绑定到了 compile 阶段。这个目标编译 src/main/java 下的所有源代码和其他任何配置的资源目录,到输出目录

resources:testResources
Resources插件的 testResources 目标绑定到了 test-resources 阶段。这个目标复制 src/test/resources 下的所有资源和其它任何的配置的测试资源目录,到测试输出目录。

compiler:testCompile
Compiler插件的 testCompile 目标绑定到了 test-compile 阶段。这个目标编译 src/test/java 下的测试用例和其它任何的配置的测试资源目录,到测试输出目录。

surefire:test
Surefire插件的 test 目标绑定到了 test 阶段。这个目标运行所有的测试并且创建那些捕捉详细测试结果的输出文件。默认情况下,如果有测试失败,这个目标会终止

jar:jar
Jar插件的 jar 目标绑定到了 package 阶段。这个目标把输出目录打包成JAR文件。

总结得来说,当我们运行mvn package,Maven运行到打包为止的所有阶段,在Maven沿着生命周期一步步向前的过程中,它运行绑定在每个阶段上的所有目标。你也可以像下面这样显式的指定一系列插件目标,以得到同样的结果:
mvn resources:resources \
compiler:compile \
resources:testResources \
compiler:testCompile \
surefire:test \
jar:jar

3. Maven坐标 (Coordinates)

Archetype插件通过名字为 pom.xml 的文件创建了一个项目。这就是项目对象模型(POM),一个项目的声明性描述。当Maven运行一个目标的时候,每个目标都会访问定义在项目POM里的信息。当 jar:jar 目标需要创建一个JAR文件的时候,它通过观察POM来找出这个Jar文件的名字。

POM为项目命名,提供了项目的一组唯一标识符(坐标),并且通过依赖 (dependencies) ,父 (parents) 和先决条件(prerequisite) 来定义和其它项目的关系。POM也可以自定义插件行为,提供项目相关的社区和开发人员的信息。

Maven坐标定义了一组标识,它们可以用来唯一标识一个项目,一个依赖,或者MavenPOM里的一个插件。看一下下面的POM。

4. Maven仓库(Repositories)

Maven仓库既是一个从远程仓库下载的构件的缓存,也允许你的项目相互依赖。

5. Maven依赖管理 (Dependency Management)

一个复杂的项目将会包含很多依赖,也有可能包含依赖于其它构件的依赖。这是Maven最强大的特征之一,它支持了传递性依赖(transitive dependencies)。假如你的项目依赖于一个库,而这个库又依赖于五个或者十个其它的库(就像Spring或者Hibernate那样)。你不必找出所有这些依赖然后把它们写在你的 pom.xml 里,你只需要加上你直接依赖的那些库,Maven会隐式的把这些库间接依赖的库也加入到你的项目中。Maven也会处理这些依赖中的冲突,同时能让你自定义默认行为,或者排除一些特定的传递性依赖。

在Maven中一个依赖不仅仅是一个JAR。它是一个POM文件,这个POM可能也声明了对其它构件的依赖。这些依赖的依赖叫做传递性依赖,Maven仓库不仅仅存贮二进制文件,也存储了这些构建的元数据(metadata),才使传递性依赖成为可能。下图展现了一个传递性依赖的可能场景。

 Maven也提供了不同的依赖范围(dependency scope)。Simple项目的 pom.xml 包含了一个依赖—— junit:junit:jar:3.8.1 ——范围是 test 。当一个依赖的范围是 test 的时候,说明它在Compiler插件运行 compile 目标的时候是不可用的。它只有在运行 compiler:testCompile 和 surefire:test 目标的时候才会被加入到classpath中。

当为项目创建JAR文件的时候,它的依赖不会被捆绑在生成的构件中,他们只是用来编译。当用Maven来创建WAR或者EAR,你可以配置Maven让它在生成的构件中捆绑依赖,你也可以配置Maven,使用 provided 范围,让它排除WAR文件中特定的依赖。 provided 范围告诉Maven一个依赖在编译的时候需要,但是它不应该被捆绑在构建的输出中。当你开发web应用的时候 provided 范围变得十分有用,你需要通过Servlet API来编译你的代码,但是你不希望Servlet API的JAR文件包含在你web应用的 WEB-INF/lib 目录中。

6. 站点生成和报告 (Site Generation and Reporting)

 另外一个Maven的重要特征是,它能生成文档和报告。在simple项目的目录下,运行以 下命令: mvn site

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值