一.简介
Maven是一个Java项目管理工具,主要功能是统一开发规范与包的依赖管理。Maven项目对象模型(POM),可以通过一小段描述信息来管理项目的构建、测试、报告等。
在开发中经常需要依赖第三方的包,包与包之间存在依赖关系,版本间还有兼容性问题,有时还里要将旧的包升级或降级,当项目复杂到一定程度时包管理变得非常重要。
Maven主要做了两件事:
如果没有Maven,你可能不得不经历下面
- 如果使用了spring,去spring的官网下载jar包;如果使用hibernate,去hibernate的官网下载jar包;如果使用Log4j,去log4j的官网下载jar包.....
- 当某些jar包有依赖的时候,还要去下载对应的依赖jar包
- 当jar包依赖有冲突时,不得不一个一个的排查
- 执行构建时,需要使用ant写出很多重复的任务代码
- 当新人加入开发时,需要拷贝大量的jar包,然后重复进行构建
- 当进行测试时,需要一个一个的运行....检查
有了Maven,它提供了三种功能:
- 依赖的管理:仅仅通过jar包的几个属性,就能确定唯一的jar包,在指定的文件pom.xml中,只要写入这些依赖属性,就会自动下载并管理jar包。
- 项目的构建:内置很多的插件与生命周期,支持多种任务,比如校验、编译、测试、打包、部署、发布...
- 项目的知识管理:管理项目相关的其他内容,比如开发者信息,版本等等
实际场景
我们开发一个项目,或者做一个小demo,比如用SSH框架,那么我们就必须将SSH框架所用的几十个依赖的jar包依次找出来并手动导入到本地文件夹,才能在代码项目里去依赖使用它,超级繁琐。
例如我要做一盘红烧排骨,我需要下列材料:
- 小排500克
- 酱油20克
- 盐5克
- 糖20克
- 茴香5克
- 姜一个
那么,我就要先去菜市场买小排,去超市买酱油,去南北货店买茴香。而且我还要自己去记,麻烦吗?
这个时候,有个超市,卖一个红烧排骨的一个包,把这些材料打包好,放在橱柜里卖。你要做的就是:
去超市
买这个红烧排骨包,里面包含了小排和所有要用到的材料。
然后,你就可以开始烧红烧小排了。至于这个红烧小排的配料怎么配,不用你操心,这个是超市做个包的配菜师傅的事情。当然,你要宫保鸡丁的配料,这个师傅也会给你配好。
Maven就是这个超市,只是它卖的不是红烧排骨,而是一个jar包已经和它有依赖关系的其他jar包。这样,你就不用再开撸java代码前,去各个网站下载各种不同的jar包了,也不用考虑它们之间的依赖关系。
而你要把这个菜做出来,那些放哪些调料和其中的先后顺序,一些翻炒步骤都用pom.xml去描述即可。
Maven生命周期
maven把项目的构建划分为不同的生命周期(lifecycle)
- 清理:即清除便编译结果,为重新编译做准备
- 编译:将.java文件变成.class文件
- 测试:针对项目中关键代码进行测试
- 报告:将测试结果进行显示
- 打包:将项目多个文件压缩成一个文件,用于安装或者部署
- 安装:将打成的包放入本地仓库
- 部署:将打成的包放到服务器上准备运行
maven中所有的执行动作(goal)都需要指明自己在这个过程中的执行位置,然后maven执行的时候,就依照过程的发展依次调用这些goal进行各种处理。
这个也是maven的一个基本调度机制。一般来说,位置稍后的过程都会依赖于之前的过程。当然,maven同样提供了配置文件,可以依照用户要求,跳过某些阶段。
Maven标准工程结构
Maven的"约束优于配置"
所谓的"约束优于配置",在maven中并不是完全不可以修改的,他们只是一些配置的默认值而已。但是除非必要,并不需要去修改那些约定内容。maven默认的文件存放结构如1.3所示。
每一个阶段的任务都知道怎么正确完成自己的工作,比如compile任务就知道从src/main/java下编译所有的java文件,并把它的输出class文件存放到target/classes中。
对maven来说,采用"约定优于配置"的策略可以减少修改配置的工作量,也可以降低学习成本,更重要的是,给项目引入了统一的规范。
Maven的版本规范
maven有自己的版本规范,一般是如下定义 <major version>.<minor version>.<incremental version>-<qualifier>
,比如1.2.3-beta-01。要说明的是,maven自己判断版本的算法是major,minor,incremental部分用数字比较,qualifier部分用字符串比较,所以要小心 alpha-2和alpha-15的比较关系,最好用 alpha-02的格式。
maven在版本管理时候可以使用几个特殊的字符串 SNAPSHOT,LATEST,RELEASE。比如"1.0-SNAPSHOT"。各个部分的含义和处理逻辑如下说明:
SNAPSHOT
这个版本一般用于开发过程中,表示不稳定的版本。
LATEST
指某个特定构件的最新发布,这个发布可能是一个发布版,也可能是一个snapshot版,具体看哪个时间最后。
RELEASE
是指仓库中最后的一个非快照版本
规范:
- 同一项目中所有模块版本保持一致
- 子模块统一继承父模块的版本
- 统一在顶层模块Pom的
<dependencyManagement/>
节中定义所有子模块的依赖版本号,子模块中添加依赖时不要添加版本号 - 开发测试阶段使用SNAPSHOT
- 生产发布使用RELEASE
- 新版本迭代只修改顶层POM中的版本
二.maven目录
bin目录:
该目录包含了mvn运行的脚本,这些脚本用来配置java命令,准备好classpath和相关的Java系统属性,然后执行Java命令。
boot目录:
该目录只包含一个文件,该文件为plexus-classworlds-2.5.2.jar。plexus-classworlds是一个类加载器框架,相对于默认的java类加载器,它提供了更加丰富的语法以方便配置,Maven使用该框架加载自己的类库。
conf目录:
该目录包含了一个非常重要的文件settings.xml。直接修改该文件,就能在机器上全局地定制Maven的行为,一般情况下,我们更偏向于复制该文件至/.m2/目录下(表示用户目录),然后修改该文件,在用户范围定制Maven的行为。
lib目录:
该目录包含了所有Maven运行时需要的java类库,Maven本身是分模块开发的,因此用户能看到诸如maven-core-3.0.jar、maven-model-3.0.jar之类的文件,此外这里还包含一些Maven用到的第三方依赖如commons-cli-1.2.jar、commons-lang-2.6.jar等等。
~/.m2目录:
本地maven仓库存储jar包文件的目录,里面存储着打包中需要的jar包,从远程下载后,本地也会留存一份。
三.setting.xml
主要用于配置maven的运行环境等一系列通用的属性,是全局级别的配置文件。包括认证信息配置,配置本地仓库路径、远程仓库地址、镜像地址。
仓库地址:存储依赖包,各种jar包
镜像地址:阿里云那种,将外网的各种依赖包备份,方便国内访问
用户配置:user.home/.m2/settings.xmlnote:用户配置优先于全局配置
{user.home} 和和所有其他系统属性只能在3.0+版本上使用。请注意windows和Linux使用变量的区别。
需要注意的是:局部配置优先于全局配置。
配置优先级从高到低:pom.xml> user settings > global settings
如果这些文件同时存在,在应用配置时,会合并它们的内容,如果有重复的配置,优先级高的配置会覆盖优先级低的。
四.仓库
在Maven世界中,任何一个依赖、插件或者项目构建的输出,都可以称为构件。得益于坐标机制,任何Maven项目使用任何一个构件的方式都是完全相同的。在此基础上,Maven可以在某个位置统一存储所有Maven项目共享的构件,这个统一的位置就是仓库。
实际的Maven项目将不再各自存储其依赖文件,它们只需要声明这些依赖的坐标,在需要的时候(例如,编译项目的时候需要将依赖加入到classpath中),Maven会自动根据坐标找到仓库中的构件,并使用它们。
为了实现重用,项目构建完毕后可生成的构件也可以安装或者部署到仓库中,供其他项目使用。
仓库的布局
任何一个构件都有其唯一的坐标,根据这个坐标可以定义其在仓库中的唯一存储路径,这便是Maven的仓库布局方式。该路经与坐标对应关系为groupId/artifactId/version/artifactId-version.packaging。
<dependency>
<groupId>com.github.pageHelper</groupId>
<artifactId>pageHelper-spring-boot-starter</artifactId>
<version>1.1.0</version>
</dependency>
那他对应的仓库的路径就是这样:
Maven仓库是基于简单文件系统存储的,我们也理解其存储方式、因此,当遇到一些与仓库相关的问题时,可以很方便的查找相关文件,方便定位问题。
仓库的分类
本地仓库
一般来说,在Maven项目目录下,没有诸如lib/这样用来存放依赖文件的目录。当Maven在执行编译或测试时,如果需要使用依赖文件,它总是基于坐标使用本地仓库的依赖文件。
默认情况下,不管在Window还是Linux下,每个用户在自己用户目录下都有一个路径名为.m2/repository/的仓库目录。
如果你想自定义本地仓库目录地址。你可以编辑文件~/.m2/settings.xml,设置localRepository元素的值为想要的仓库地址,例如:
<settings>
<localRepository>D:\java\repository\</localRepository>
</settings>
这样,该用户的本地仓库地址就被设置成了 D:\java\repository\。
需要注意的是,默认情况下,~/.m2/settings.xml文件不存在,用户需要从Maven安装目录复制$M2_HOME/conf/settings.xml文件再进行编辑。
远程仓库-中央仓库
由于最原始的本地仓库是空的,Maven必须知道至少一个可用的远程仓库,才能在执行Maven命令的时候下载到需要的构件。中央仓库就是这样一个默认的远程仓库,Maven的安装文件自带了中央仓库的配置。
中央仓库包含了这个世界上绝大多数流行的开源Java构件,以及源码、作者信息、SCM,信息、许可证信息等,每个月这里都会接受全世界Java程序员大概1亿次的访问,它对全世界Java开发者的贡献由此可见一斑。
远程仓库-私服
私服是一种特殊的远程仓库,它是架设在局域网内的仓库服务,私服代理广域网上的远程仓库,供局域网内的Maven用户使用。当Maven需要下载构件的时候,它从私服请求,如果私服上不存在该构件,则从外部的远程仓库下载,缓存在私服上之后,再为Maven的下载请求提供服务。因此,一些无法从外部仓库下载到的构件也能从本地上传到私服上供大家使用。
私服的好处:
- 节省自己的外网速度
- 加速Maven构建
- 部署第三方构建
- 提高稳定性,增强控制
- 降低中央仓库的负荷
仓库使用顺序
三者之间的关系是,当我们在项目中依赖一个jar包时,Maven程序会先去本地仓库中找,如果没找到就回去私服找,如果还是没有,最后就回去中央仓库找。其过程如下图:
jar包的类型
如果从仓库类型上分,则分为 release发布仓库 和 snapshot快照仓库
- snapshot快照仓库用于保存开发过程中的不稳定版本
- release正式仓库用来保存稳定的发行版本
- 定义一个组件/模块为快照版本 只需要在pom文件中的该模板的版本号后面加上 -SNAPSHOT就可以了. 注意:必须是大写
- maven会根据模块的版本号(pom文件中的
<version>
版本号</version>
)中是否带有-SNAPSHOT来判断这个是快照版本还是正式版本
如果是快照版本:
在mvn deploy时会自动发布到快照版本库中。而使用快照版本的模块,在不更改版本号的情况下直接编译打包时,maven会自动从镜像服务器上下载最新的快照版本。
如果是正式发布版本:
那么在mvn deploy时会自动发布到正式版本库中。而使用正式版本的模块在不更改版本号的情况下,编译打包时,如果本地已经存在该版本的模块则使用本地的而不是主动去镜像服务器上下载。
mvn在上传jar包到私服和正常构建进行依赖下载时,都会在本地存一份。快照版本包适合在测试或者UAT环境中使用,用于快速迭代,不用改版本号一直对同版本的jar包进行修改。正式包适合shengchan生产环境,每次jar包功能变更都要打版本号。
五.常用maven命令
mvn clean
表示运行清理操作(会默认把target文件夹中的数据清理)
mvn clean compile
表示先运行清理之后运行编译,会将代码编译到target文件夹中
mvn clean test
运行清理和测试
mvn clean package
package命令完成了项目编译 单元测试 打包功能,但没有把打包的可执行jar包(war包或其它形式的包)部署到本地maven仓库和远程maven私服仓库
mvn clean install
isntall命令完成了项目编译 单元测试 打包功能,同时把打包的可执行jar包(war包或其它形式的包)部署到本地maven仓库,但没有部署到远程maven私服仓库
mvn clean deploy
deploy命令完成了项目编译 单元测试 打包功能,同时把打包的可执行jar包(war包或其它形式的包)部署到本地maven仓库和远程maven私服仓库
上面的命令大部分都是连写的,大家也可以拆分分别执行,这是活的,看个人喜好以及使用需求,Eclipse Run as对maven项目会提供常用的命令
六.pom.xml
POM是项目对象模型(Project Object Model)的简称,它是Maven项目中的文件,使用XML表示,名称叫做pom.xml。
作用范围是局部,每个项目构建都要有个属于那个项目的pom.xml
在Maven中,当谈到Project的时候,不仅仅是一堆包含代码的文件。一个Project往往包含一个配置文件,包括了与开发者有关的,缺陷跟踪系统,组织与许可,项目的URL,项目依赖,以及其他。
它包含了所有与这个项目相关的东西。事实上,在Maven世界中,project可以什么都没有,甚至没有代码,但是必须包含pom.xml文件。
setting.xml主要用于配置maven的运行环境等一系列通用的属性,是全局级别的配置文件;
而pom.xml主要描述了项目的maven坐标,依赖关系,开发者需要遵循的规则,缺陷管理系统,组织和licenses,以及其他所有的项目相关因素,是项目级别的配置文件。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。