您的位置:首页 > 运维架构

maven实战(一)简单mvn构建项目详解

2017-03-21 14:34 316 查看

创建简单工程

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


archetype:create 在maven 3.0.5中已经舍弃,使用generate替代

相关mvn命令

archetype:generate:archetype被定义为“一个原始的模型或者类型,在它之后其它类似的东西与之匹配;一个*原型(prototype)”,Maven有许多可用的archetype,从生成一个简单的Swing应用,到一个复杂的Web应用。本章我们用最基本的archetype来创建一个入门项目的骨架。这个插件的前缀是“archetype”,目标为“generate”。

-Dname=value:使用 -D 属性这样的形式 1 ,类似于你通过命令行向Java虚拟机传递系统属性,例如-DgroupId是给groupId设置值,-DartifactId是给artifactId设置值。

运行以上mvn命令后已经生成了一个项目,看一下Maven在simple目录下创建的目录结构:

simple/

simple/pom.xml

simple/src

src/main

src/main/java/

simple/target

简单构建

mvn install:

想要构建打包这个应用,在包含 pom.xml 的目录下运行mvn install,会下载项目中所有依赖,并在target目录下生成所有编译后的文件,产生一个jar包(默认打包方式是jar包)。

mvn help:effective-pom:

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

maven核心概念

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

Archetype插件create 目标。Maven第二次运行是一个生命周期阶段– install 。为了运行单个的Maven插件目标,我们使用mvn archetype:create这样的语法,这里 archetype 是一个插件标识create 目标标识。当Maven运行一个插件目标,它向标准输出打印出插件标识和目标标识。

Maven插件(Plugins):一个Maven插件是一个单个或者多个目标的集合

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

目标(Goals):一个目标是一个明确的任务

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

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

目标定义了一些参数,这些参数可以定义一些明智的默认值。在 archetype:create 这个例子中,我们并没有在命令行中指定这个目标创建什么类型的archetype,我们简单的传入一个 groupId 和一个 artifactId 。这是我们对于约定优于配置(convention overconfiguration)的第一笔。这里 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插件。

2.maven生命周期 (Lifecycle)

生命周期是包含在一个项目构建中的一系列有序阶段

maven支持许多不同的生命周期,但是最常用的生命周期是默认的Maven生命周期,这个生命周期中一开始的一个阶段是验证项目的基本完整性,最后的一个阶段是把一个项目发布成产品。生命周期的阶段被特地留得含糊,单独的定义为验证(validation),测试(testing),或者发布(deployment),而他们对不同项目来说意味着不同的事情例如,打包(package)这个阶段在一个项目里生成一个JAR,它也就意味着“将一个项目打成一个jar”,而在另外一个项目里,打包这个阶段可能生成一个WAR文件。

生命周期图



这个生命周期能让开发人员从一个Maven项目跳到另外一个Maven项目,而不用知道太多每个项目构建的细节。如果你能够构建一个Maven项目,那么你就能构建所有的Maven项目。

生命周期将会有文来详细阐述,此处暂略过。

3.Maven坐标 (Coordinates)

一个项目的 groupId:artifactId:version 使之成为一个独一无二的项目

(1)maven坐标构成:

Archetype插件通过名字为 pom.xml 的文件创建了一个项目。这就是项目对象模型(POM),一个项目的声明性描述。当Maven运行一个目标的时候,每个目标都会访问定义在项目POM里的信息。当 jar:jar 目标需要创建一个JAR文件的时候,它通过观察POM来找出这个Jar文件的名字。当 compiler:compile 任务编译Java源代码为字节码的时候,它通过观察POM来看是否有编译目标的参数。目标在POM的上下文中运行。目标是我们希望针对项目运行的动作,而项目是通过POM定义的。POM为项目命名,提供了项目的一组唯一标识符(坐标),并且通过依赖(dependencies) ,父 (parents) 和先决条件(prerequisite) 来定义和其它项目的关系。POM也可以自定义插件行为,提供项目相关的社区和开发人员的信息。

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

(2)maven坐标用处:maven中的项目可以通过坐标使用特定构件的依赖

在其它“Maven化”项目构成的巨大空间中,的这四个元素是定位和使用某个特定项目的关键因素。Maven仓库(repositories)(公共的,私有的,和本地的)是通过这些标识符来组织的。当一个项目被安装到本地的Maven仓库,它立刻能被任何其它的项目所使用。而我们所需要做的只是,在其它项目用使用Maven的唯一坐标来加入对这个特定构件的依赖

4.Maven仓库(Repositories)

maven公有中央仓库

当你第一次运行Maven的时候,你会注意到Maven从一个远程的Maven仓库下载了许多文件。如果这个简单的项目是你第一次运行Maven,那么当触发resources:resource目标的时候,它首先会做的事情是去下载最新版本的Resources插件。在Maven中,构件和插件是在它们被需要的时候从远程的仓库取来的。初始的Maven下载包的大小相当的小(1.8兆),其中一个原因是事实上这个初始Maven不包括很多插件。它只包含了几近赤裸的最少值,而在需要的时候再从远程仓库去取。Maven自带了一个用来下载Maven核心插件和依赖的远程仓库地址(http://repo1.maven.org/maven2)。

maven定制仓库

项目依赖于一些既不免费也不公开的包。在这种情况下,你需要要么在你组织的网络里安装一个定制的仓库,要么手动的安装这些依赖。默认的远程仓库可以被替换,或者增加一个你组织维护的自定义Maven仓库的引用。有许多现成的项目允许组织管理和维护公共Maven仓库的镜像。

maven本地仓库

mvn install项目的构件安装到你的本地仓库

Maven从远程仓库下载构件和插件到你本机上,存储在你的本地Maven仓库里。一旦Maven已经从远程仓库下载了一个构件,它将永远不需要再下载一次,因为maven会首先在本地仓库查找插件,然后才是其它地方。在Windows XP上,你的本地仓库很可能在 C:\Documents and Settings\USERNAME.m2\repository ,在Windows Vista上,会是 C:\Users\USERNAME.m2\repository 。在Unix系统上,你的本地仓库在 ~/.m2/repository 。

当你创建像前一节创建的简单项目时, install 阶段执行一个目标,把你项目的构件安装到你的本地仓库。在你的本地仓库,你应该可以看到我们的简单项目创建出来的构件。

5.Maven依赖管理 (Dependency Management)

(1)传递性依赖(transitive dependencies)

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

当你把项目的构件安装到本地仓库时,你会发现在和JAR文件同一目录下,Maven发布了一个稍微修改过的 pom.xml 的版本。存储POM文件在仓库里提供给其它项目了该项目的信息,其中最重要的就是它有哪些依赖。如果项目B依赖于项目A,那么它也依赖于项目A的依赖。当Maven通过一组Maven坐标来处理依赖构件的时候,它也会获取POM,通依赖的POM来寻找传递性依赖。那些传递性依赖就会被添加到当前项目的依赖列表中。在Maven中一个依赖不仅仅是一个JAR。它是一个POM文件,这个POM可能也声明了对其它构件的依赖。这些依赖的依赖叫做传递性依赖,Maven仓库不仅仅存贮二进制文件,也存储了这些构建的元数据(metadata),才使传递性依赖成为可能。

依赖范围(dependency scope)

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

scope

compile:缺省值,适用于所有阶段,会随着项目一起发布

provided:类似compile,期望JDK、容器或使用者会提供这个依赖。如servlet.jar。

runtime:重点内容,只在运行时**使用,如JDBC驱动,适用运行和测试阶段。

test:重点内容,只在测试时使用,用于编译和运行测试代码不会随项目发布

system,类似provided,需要显式提供包含依赖的jarMaven不会在Repository中查找它。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息