什么是Maven?Maven能做什么?使用Maven的优点(对比ant打包)?怎么使用Maven?
(ps:适合0基础初学者,大神请飘过)
一、什么是Maven
1、定义介绍
Maven
项目对象模型(POM),可以通过一小段描述信息来管理项目的构建,报告和文档的软件
项目管理工具
。
Maven是一个
项目管理
和
综合工具
。
Maven
提供了开发人员
构建一个完整的生命周期框架
。开发团队可以自动完成项目的基础工具建设,Maven使用标准的目录结构和默认构建生命周期。
在多个开发团队环境时,Maven可以设置按标准在非常短的时间里完成配置工作。由于大部分项目的设置都很简单,并且可重复使用,Maven让开发人员的工作更轻松,同时创建
报表
,
检查
,
构建
和
测试自动化
设置。
Maven提供了开发人员的方式来管理:
- Builds 构建
- Documentation 文档
- Reporting 报告
- Dependencies 依赖
- SCMs 自动化
- Releases 版本
- Distribution 分布
- mailing list 邮件列表
概括地说,Maven简化和标准化项目建设过程。处理编译,分配,文档,团队协作和其他任务的无缝连接。 Maven增加可重用性并负责建立相关的任务。最强大的功能就是能够
自动下载项目依赖库
。
Maven主要目标是提供给开发人员:
- 项目是可重复使用,易维护,更容易理解的一个综合模型。
- 插件或交互的工具,这种声明性的模式。
Maven项目的结构和内容在一个
XML
文件中声明,
pom.xml
项目对象模型(POM),这是整个Maven系统的基本单元。有关详细信息,请参阅
Maven POM
的部分。
2、Maven资源库
(
点击蓝色文字进入链接
)
//构建过程依赖的三种仓库
1、
本地Maven仓库
2、
Maven中央库
3、
链接远程仓库。
4、
Maven加载jar包到本地仓库
Maven 位置,中央和远程存储库配置和解释,有些术语可能需要在 Maven 使用前理解。
Maven 的本地资源库是用来存储项目的依赖库,默认的文件夹是 “.m2” 目录,可能需要将其更改为另一个文件夹。
Maven 中央存储库是 Maven 用来下载所有项目的依赖库的默认位置。
并非所有的库存储在Maven的中央存储库,很多时候需要添加一些远程仓库来从其他位置,而不是默认的中央存储库下载库。
这里的文章是关于传统方式和Maven方式的依赖库的不同,并说明 Maven 会从那里搜索这些库。
很多库仍然不支持 Maven 的 pom.xml 的概念,这里有一个指南来说明如何包括“非Maven支持”库到 Maven 本地资源库中。
二、Maven能做什么
项目构建
,
版本控制
,
库依赖
大概用到的功能就这三个
1、Maven的俗话翻译
上面Maven介绍中有很多的专业术语和专业词汇,上面的介绍这么说有点太高大上了,接地气一点来说吧:
Maven希望把软件开发中的一些最佳实践和模式都整合和固化下来,这样使用Maven来进行开发时,开发过程更爽,生产出来的软件更棒,具有以上所罗列的各种特性。
这几种特性对于一个团队一起高效的开发协作的确是非常重要的。
最佳实践
:Maven最初的诞生就是希望Apache的一些项目能够以相同的方式来开发和构建,这样一个开发者从一个项目转到另外一个项目工作的时候能够更加轻松地切换。因为项目的开发、测试、文档生成、报表和部署,都具有一些共同的特征,这些特征就可以认为是软件开发过程中的一些最佳实践,当这些最佳实践成为共识,开发的协作必然会更加高效。
那么Maven要做的就是把这些最佳实践固化成一个通用的项目管理方法。尽管对于不同的项目,开发中各个阶段会有所不同,但是确实可以找到一条普遍适用的路径,Maven将这条路径以非常清晰的方式结合各种实践模式提供给开发者。
模式
:我们创建项目之后会考虑一下问题:(我的代码放到哪?我的测试代码放到哪?我的资源放到哪?再大粒度一些比如项目的依赖如何管理,再大到整个项目构建的生命周期模式(比如:通用的构建过程包含哪些阶段?)
都是Maven这个基础设施要提供给大家的,是Maven强制大家形成共同的认知。这样大家就能更快速地生产出棒棒哒的软件。
举个栗子
在maven之前,小王每一天来公司都胆战心惊,不知道那个实习生会昨天加班到十点干了啥,不幸的是他的模块要依赖实习生的,于是小王每天上班的前四个小时都会以下事情:
检索最新代码;
while(小王还没崩溃){
单元测试;
更新代码;
跑不通;
}
当小王崩溃了,他跑过去问实习生:“起不来,什么情况,你动了啥?”实习生给出了经典回答:“在我电脑上一直很好啊。”小王一气之下,拷贝实习生所有jar包替换,终于工程起来了。小王如此死循环了一周,感觉项目这么继续下去要崩,于是找到了maven。
maven是啥,是绝佳的构建工具,帮你管理了从项目的开始到测试的所有过程,你可以用它(准确的说是maven的各个插件)编译、测试、清理、部署。maven同样可以帮你管理jar包,只要你在pom中配好相关的配置,maven就可以贴心地帮你下载好相应的依赖以及多重依赖。
有了maven一般会配合hudson一起食用。maven管理你的项目的架构,hudson用于持续继承,及时发现团队项目中的潜在危险。
我们来看一下有了maven之后是什么样子的?
小王的模块不幸依赖了实习生的模块。小王每天去上班首先看看hudson有没有给项目经理发邮件。而maven下面的模块依赖一直就是用稳定版的,项目稳如狗,美好的一天开始了。
2、项目的构建
Maven这个基础设施落地下来,最重要的还是一个构建工具(虽然Maven创建者们不屑和Ant这样的构建工具相提并论)。所以介绍Maven,必然还是需要先了解构建。
构建是什么呢?简单地说,构建就是软件项目生产的整个过程,比如这个过程应该包括:
- 文档和代码的生成(有些项目会使用代码自动生成工具,比如数据库访问代码的逆向工程)
- 代码的编译、测试和打包
- 打包好的代码进行分发或者部署
大家看看,项目的构建可绝不仅仅是编译软件这件事情。除了写代码,在项目层面做的大部分工作,都包含在构建的过程中。有了Maven,构建中的这些过程都能够进行良好的定义(模式、固化、共识,记住这些关键词哪),而且Maven能够帮我们串起来形成一个自动构建过程,这样比我们手动执行要高效得多。
3、项目依赖管理
Java最大的一个优势之一应该是整个生态中无数的框架和API,我们创建实际的项目不可避免的都需要用到这些框架和API,而它们通常都是以JAR包的形式提供。 相信很多人都经历过JAR Hell的问题吧,事实上让一个项目所依赖的依赖的外部jar包保持正确的版本和最新的状态,是意见非常苦逼的事情。我们编译项目的时候,需要在classpath上存放依赖的jar包(不管直接使用Eclipse还是手动维护Ant)。而且这些外部的jar包还会有其他依赖。你一定经历过递归地一个个去下载所有这些外部依赖,并且要确保下载的版本都是正确的,当项目越来越复杂的时候,这是意见极其麻烦的事情。
Maven现在来拯救我们了,Maven可以自动帮我们做依赖管理,我们需要做的就是在pom文件里指定依赖jar包的名称、版本号,Maven会自动下载,递归地去下载依赖的进一步依赖这件事情我们也不需要管了。
Maven还提供一个非常方便的功能:快照依赖。快照依赖指的是那些还在开发中的内部依赖包。与其经常地更新版本号来获取最新版本,不如你直接依赖项目的快照版本。
快照版本的每一个build版本都会被下载到本地仓库,即使该快照版本已经在本地仓库了。总是下载快照依赖可以确保本地仓库中的每一个build版本都是最新的。
这对我们快速迭代开发是一个非常酷的特性。
三、Maven的优点(与ant对比)
(一)、Maven的优点
1、为什么有maven?构建是程序员每天要做的工作,而且相当长的时间花在了这上面,而maven使这系列的工作完全自动化。
2、我们一直在寻找避免重复的方法,设计的重复,文档的重复,编码的重复,构建的重复等,maven是跨平台的,最大的消除了构建的重复。
3、maven不仅是构建工具,它还是依赖管理工具和项目管理工具,提供了中央仓库,能够帮我们自动下载构件。
4、为了解决的依赖的增多,版本不一致,版本冲突,依赖臃肿等问题,它通过一个坐标系统来精确地定位每一个构件(artifact)。
5、还能帮助我们分散在各个角落的项目信息,包括项目描述,开发者列表,版本控制系统,许可证,缺陷管理系统地址。
6、maven还为全世界的java开发者提供了一个免费的中央仓库,在其中几乎可以找到任何的流行开源软件。通过衍生工具(Nexus),我们还能对其进行快速搜索
7、maven对于目录结构有要求,约定优于配置,用户在项目间切换就省去了学习成本。
以下是通俗的理解
1)平时我们开发项目时,一般都是一个项目就是一个工程。我们划分模块时,都是使用package来进行划分。但是,当项目很大时,有很多子模块时,即使是package来进行划分,也是让人眼花缭乱。
优点一:项目非常大时,可借助Maven将一个项目拆分成多个工程,最好是一个模块对应一个工程,利于分工协作。而且模块之间还是可以发送消息的。
(2)同一项目的jar包 复制 和 粘贴到WEB/INF/lib下
问题:同样的jar包重复出现在不同的工程中,一方面浪费空间,同时也让工程臃肿
优点二:借助Maven,可将jar包仅仅保存在“仓库”中,有需要该文件时,就引用该文件接口,不需要复制文件过来占用空间。
(3)如果jar包都到各个官网网站下载,会浪费很多时间,而且可能不全。
优点三:借助Maven可以以规范的方式下载jar包,因为所有的知名框架或第三方工具的jar包已经按照统一的规范存放到了Maven的中央仓库中。
(4)一个jar包依赖的其他jar包可能没导入到项目而导致项目跑不起来。
优点四:Maven会自动将你要加入到项目中的jar包导入,不仅导入,而且还会将该jar包所依赖的jar包都自动导入进来。而且是导入该包的最新版本
(二)、ant优点和作用
Ant的作用:是一种基于Java的build工具
- 可以用ant编译java类,生成class文件
- ant可以自定义标签、配置文件,用于构建。
- ant可以把相关层构建成jar包 。
- ant把整个项目生成web包,并发布到Tomcat
Ant的优点:
- 跨平台性:Ant是纯Java语言编写的,因此具有很好的跨平台性。
- 操作简单:Ant是由一个内置任务和可选任务组成的。Ant运行时需要一个XML文件(构建文件)。
- Ant通过调用target树,就可以执行各种task:每个task实现了特定接口对象。由于Ant构建文件时XML格式的文件,所以很容易维护和书写,而且结构很清晰。
- Ant可以集成到开发环境中:由于Ant的跨平台性和操作简单的特点,它很容易集成到一些开发环境中去。
(三)、区别
Maven除了具备Ant的功能外,还增加了以下主要的功能:
- 使用Project Object Model来对软件项目管理;
- 内置了更多的隐式规则,使得构建文件更加简单;
- 内置依赖管理和Repository来实现依赖的管理和统一存储;
- 内置了软件构建的生命周期;
Maven的优点:
- 拥有约定,知道你的代码在哪里,放到哪里去
- 拥有一个生命周期,例如执行 mvn install就可以自动执行编译,测试,打包等构建过程
- 只需要定义一个pom.xml,然后把源码放到默认的目录,Maven帮你处理其他事情
- 拥有依赖管理,仓库管理
整体的比较:
Ant将提供了很多可以重用的task,例如 copy, move, delete以及junit单元测试Maven则提供了很多可以重用的过程。我们可以把 Maven看成是一个"build container"这个容器可以让我们重用从一系列的项目中抽像出来的build过程。
使用过Ant的朋友都会有这样的体会吧。Ant提供的task级别描述,我们可以通过想写shell一样一个Java项目的build过程来进行描述。我们可以写好一个build.xml文件,来解决我们在Java程序运行编译过程中需要解决的classpath,以及相关参数的配置问题,只有是项目中的主要结构以及依赖的库不变,我们很少去修改build.xml。但是如果我们要开发一个新的项目即使原有项目的build.xml写的即使再好,其能够复用得模块还是比较少的。特别是对项目的结构进行修改后,想不修改build.xml都很困难。
这是因为Ant所提供的可重用的task粒度太小,虽然灵活性很强,但是我们需要纠缠很多细节的东西。
正如你所在使用Servlet容器时,并没有告诉它如何去解包WAR文件,在你使用Maven时,你也不需要告诉Maven如何build你的项目。Maven提供了一套抽象层用来分离项目的build逻辑。许多人一开始就被Maven所提供的依赖管理(可以通过XML来描述项目所依赖的库的关系)打动,但是使用
Maven的主要好处还是它能为提供一个标准的开发构架用来对多个项目进行管理。
依赖管理只是这个标准开发构架所提供的一个副产品。
如果想让Maven实现某个build过程,例如compile, test, install,我们可以通过写plugin的方式,很容易就实现build过程的复用。Maven可以为我们提供一个很舒适的build环境,我们不需要通过build.xml定义繁琐的build过程,只需要告诉这些build过程的plugin,我现在的文件依赖的那些第三方库,我需要实现什么样的build功能,就足够了
。那些繁琐的路径配置信息,以及复杂的第三方库下载设置,你通通不用考虑, Maven 都帮你实现了。
四、Maven怎么用
1、
Maven环境安装
(自行百度)
https://www.jianshu.com/p/191685a33786
2、
创建 Maven 项目
(1)Interactive Mode**(交互模式)**
我们不妨创建一个 Java Web 项目,只需在 cmd 中输入:
mvn archetype:generate
随后 Maven 将下载 Archetype 插件及其所有的依赖插件,这些插件其实都是 jar 包,它们存放在您的 Maven 本地仓库中。
在 cmd 中,您会看到几百个 Archetype(原型),可将它理解为项目模板,您得从中选择一个。
我们的目标是创建 Java Web 项目,所以您可以选择 maven-archetype-webapp(可以在 cmd 中进行模糊搜索),随后 Maven 会与您进行一些对话,Maven 想知道以下信息:
- 项目 Archetype Version(原型版本号)是什么?—— 可选择 1.0 版本
- 项目 groupId(组织名) 是什么?—— 可输入 com.smart
- 项目 artifactId(构件名)是什么?—— 可输入 smart-demo
- 项目 version(版本号)是什么?—— 可输入 1.0
- 项目 package(包名)是什么?—— 可输入 com.smart.demo
以上这种方式称为 Interactive Mode**(交互模式)**。
(2)Batch Mode**(批处理模式)**
或许觉得这样的交互过于繁琐,那么您也可以尝试仅使用一条命名,来完成同样的事情:
<
parent
>
<
groupId
>
com.smart
groupId
>
<
artifactId
>
smart-demo
artifactId
>
<
version
>
1.0
version
>
parent
>
mvn archetype:generate -DinteractiveMode=false -DarchetypeArtifactId=maven-archetype-webapp -DgroupId=com.smart -DartifactId=smart-demo -Dversion=1.0
对于maven中archetypeArtifactId的类型的选择:
我们的目标是创建 Java Web 项目,所以您可以选择 maven-archetype-webapp(可以在 cmd 中进行模糊搜索大概有41种)
以上这种方式成为 Batch Mode**(批处理模式)**。
(3) IDEA 直接创建一个 Maven 项目
当然,还有第三种选择,使用 IDE 来创建 Maven 项目,您可以使用 Eclipse、NetBeans、IDEA 来创建 Maven 项目,操作过程应该是非常简单的。
您也可以使用 IDEA 直接打开一个 Maven 项目,只需要 File -> Open -> 选择 pom.xml,那么下面您就可以在 IDEA 中开发 Maven 项目了
其实这个目录结构还不太完备,我们需要手工添加几个目录上去,最终的目录结构看起来是这样的:
我们手工创建了三个目录:
- src/main/java
- src/test/java
- src/test/resources
为什么自动生成的目录不完备?确实挺无语的,我们就不要去纠结了。不过有必要稍微解释一下这个 Maven 目录规范:
-
- main 目录下是项目的主要代码,test 目录下存放测试相关的代码。
- 编译输出后的代码会放在target 目录下(该目录与 src 目录在同一级别下,这里没有显示出来)。
- java 目录下存放 Java 代码,resources 目录下存放配置文件。
- webapp 目录下存放 Web 应用相关代码。
- pom.xml 是 Maven 项目的配置文件。
其中 pom.xml 称为 Project Object Model(项目对象模型),它用于描述整个 Maven 项目,所以也称为 Maven 描述文件。
(4)理解 pom.xml
当 您打开自动生成的 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
>com.smart
groupId
> <
artifactId
>smart-demo
artifactId
> <
version
>1.0
version
> <
packaging
>jar
packaging
> <
name
>smart-demo Maven Webapp
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
> <
build
> <
finalName
>smart-demo
finalName
>
build
>
project
>
从上往下简要说明一下:
- modelVersion:这个是 POM 的版本号,现在都是 4.0.0 的,必须得有,但不需要修改。
- groupId、artifactId、version:分别表示 Maven 项目的组织名、构件名、版本号,它们三个合起来就是 Maven **坐标,根据这个坐标可以在 Maven 仓库中对应唯一的 **Maven 构件。
- packaging:表示该项目的打包方式,war 表示打包为 war 文件,默认为 jar,表示打包为 jar 文件。
- name、url:表示该项目的名称与 URL 地址,意义不大,可以省略。
- dependencies:定义该项目的依赖关系,其中每一个 dependency 对应一个 Maven 项目,可见 Maven 坐标再次出现,还多了一个 scope,表示作用域(下面会描述)。
- build:表示与构建相关的配置,这里的 finalName 表示最终构建后的名称 smart-demo.war,这里的 finalName 还可以使用另一种方式来定义(下面会描述)。
截图窗口显示树状形图来表示pom.xml,那么会更加清晰:
Maven project树状形图
可见,除了项目的基本信息(Maven 坐标、打包方式等)以外,每个 pom.xml 都应该包括:
- Lifecycle(生命周期)
- Plugins(插件)
- Dependencies(依赖)
Lifecycle 是项目构建的生命周期,它包括 9 个 Phase(阶段)。
大家知道,Maven 是一个核心加上多个插件的架构,而这些插件提供了一系列非常重要的功能,这些插件会在许多阶段里发挥重要作用。
阶段*插件*作用
clean
clean 清理自动生成的文件,也就是 target 目录
validate
由 Maven 核心负责 验证 Maven 描述文件是否有效
compile
compiler、resources 编译 Java 源码
test
compiler、surefire、resources 运行测试代码
package
war 项目打包,就是生成构件包,也就是打 war 包
verify
由 Maven 核心负责 验证构件包是否有效
install
install 将构件包安装到本地仓库
site
site 生成项目站点,就是一堆静态网页文件,包括 JavaDoc
deploy
deploy 将构件包部署到远程仓库
以上表格中所出现的插件名称实际上是插件的别名(或称为前缀),比如:compiler 实际上是 org.apache.maven.plugins:maven-compiler-plugin:2.3.2,这个才是 Maven 插件的完全名称。
每个插件又包括了一些列的 Goal(目标),以 compiler 插件为例,它包括以下目标:
-
- compiler:help:用于显示 compiler 插件的使用帮助。
- compiler:compile:用于编译 main 目录下的 Java 代码。
- compiler:testCompile:用于编译 test 目录下的 Java 代码。
可见,插件目标才是具体干活的人,一个插件包括了一个多个目标,一个阶段可由零个或多个插件来提供支持。
我们可以在 pom.xml 中定义一些列的项目依赖(构件包),每个构件包都会有一个 Scope(作用域),它表示该构件包在什么时候起作用,包括以下五种:
- compile:默认作用域,在编译、测试、运行时有效
- test:对于测试时有效
- runtime:对于测试、运行时有效
- provided:对于编译、测试时有效,但在运行时无效
- system:与 provided 类似,但依赖于系统资源
3、
发布第三方Jar到本地库中:
Maven指令打包
Maven中的三个重要参数(可以看做是三级文件夹目录)
<
dependency
>
<
groupId
>
org.springframework
groupId
>
<
artifactId
>
context
artifactId
>
<
version
>
3.1.0
version
>
dependency
>
Maven指令为
mvn install:install-file -Dfile=jar包所在的位置 -DgroupId=上面的groupId -DartifactId=上面的artifactId -Dversion=上面的version -Dpackaging=jar
-Dfile :jar包的绝对路径((D:\mvn\spring-context-support-3.1.0.RELEASE.jar)
-DgroupId:GroupID是项目组织唯一的标识符,实际对应JAVA的包的结构,是main目录里java的
目录结构
。
-DartifactId:ArtifactID就是项目的唯一的标识符,实际对应项目的名称,就是项目根目录的名称。
groupId一般分为多个段,这里只说两段,第一段为域,第二段为公司名称。域又分为org、com、cn等等许多,其中org为非营利组织,com为商业组织。举个apache公司的tomcat项目例子:这个项目的groupId是org.apache,它的域是org(因为tomcat是非营利项目),公司名称是apache,artigactId是tomcat。
--Dversion :版本号
执行上述mvn命令之后发布第三方jar包到本地存放在电脑的Maven库存中,路径为~/.m2/repository下,生成文件在本地库存具体在org/springframework/context文件夹下,随不同版本号增加3.1.0 3.1.1 ……
4、
常使用 Maven 命令
前面我们已经使用了几个 Maven 命令,例如:mvn archetype:generate,
mvn install:install-file
等。其实,可使用两种不同的方式来执行 Maven 命令:
方式一:mvn <插件>:<目标> [参数]
方式二:mvn <阶段>
现在我们接触到的都是第一种方式,而第二种方式才是我们日常中使用最频繁的,例如:
- mvn clean:清空输出目录(即 target 目录)
- mvn compile:编译源代码
- mvn package:生成构件包(一般为 jar 包或 war 包)
- mvn install:将构件包安装到本地仓库
- mvn deploy:将构件包部署到远程仓库
执行 Maven 命令需要注意的是:必须在 Maven 项目的根目录处执行,也就是当前目录下一定存在一个名为 pom.xml 的文件。
2018/04/11