maven简介
maven是一个项目管理工具,包含项目对象(POM,project Object Model),项目的生命周期(Project Life Cycle),依赖管理系统(dependency Manager System)和各种插件。 插件主要用来实现生命周期的各个阶段的目标。
项目构建
- 文档和代码的生成
- 代码的编译,测试和打包
- 打包好的代码进行分发和部署
maven能够很好的帮我们自动的构建这个过程。
maven仓库
maven仓库存在三种类型:
- 本地仓库(local):maven从远程仓库下载下来的构件会存放在本地仓库中,项目可以从本地maven仓库中获取自己依赖的文件。
- 中央仓库(central):在中央仓库中会包含大量常用的库,可以指定中仓库的位置,默认是maven社区提供的仓库。
- 远程私服仓库(remote):私服一般是公司内部使用的库,当我们在本地和中央仓库都没有找到构件时,会尝试从我们配置的远程私服仓库中获取。
maven依赖的搜索顺序
- 先从本地仓库获取
- 如果步骤1中没找到,则到中央仓库搜索。
- 如果在中央仓库没有找到,则在私服仓库中查找,如果没有配置配置私服仓库,直接抛出错误。
- 如果配置了私服仓库,则直接到私服仓库中查找。
修改配置文件
本地仓库的位置信息:%\maven\apache-maven-3.6.0\conf\setting.xml, 找到如下的配置信息。
可以修改标签内容指定本地仓库位置信息。
修改中央仓库的位置:
找到所有pom文件的父文件,位置在:
%/lib/maven-model-builder-${version}.jar,打开该jar文件,在\org\apache\maven\model\pom-40.0.xml中修改标签为中央仓库的位置信息。
maven构件和坐标
maven构件:在maven中每个项目都可以输出成构件。
maven坐标:每个构件都需要一组坐标来进行定位标识。
maven构件标识
- groupId : 当前构件属于哪个组织的组织名,通常情况下第一段为域,第二段为公司名。如tomcat为例,org.apache。
- artifactId : 项目的唯一标识,实际对应的名称,就是项目根目录名称。
- version : 该构件的版本号。
- packing:打包方式,比如是jar,war,pom
- classifier:通常使用在同一个pom下,具有不同输出内容的构件。
maven依赖和依赖冲突
maven的依赖分为直接依赖和间接依赖。
依赖冲突
为什么会产生依赖冲突?
比如有构件A依赖 构件B,构件C:
但是B又依赖于D(1.0.0), C依赖于D(1.1.1)
此时就会产生冲突,到底依赖于D(1.0.0)还是D(1.1.1)
怎么解决依赖冲突呢?
第一原则:
路径最近者优先:在若干条依赖冲突中,选择最短那条依赖路径的结果作为最终结果。
第二原则:
第一声明优先:在路径长度相同的时候,选择在pom文件中最先被声明的对象最为最终结果。
第三原则:
覆盖原则:在前面的几条原则的情况下依旧不能解决,那么选择最后一个被声明的依赖作为最终结果。
maven的依赖范围:
- compile:编译依赖范围(默认),配置的依赖对于编译,测试,运行都有效,在这个三个周期内都会使用到配置jar包。
- test:测试依赖范围。只能在测试中使用,其他时候无法使用,典型的是junit中pom文件。
- provided:此依赖范围,对于编译测试和运行有效 ,对运行时无效。
- runtime:运行时依赖范围,对于测试和运行有效,但是在编译的时候无效,典型的是jdbc驱动的实现。
- system:系统依赖范围,只有通过systemPath元素显示地指定依赖文件的路径,不依赖maven仓库解析,所以造成建构的不可移植。
暴力解决依赖冲突?
在标签中定义每个来剔除依赖。
maven生命周期
一个典型的maven的生命周期:
在上述的项目的构建过程中,还包含一下三个标准流程
- clean: 项目的清理
- default(或build):项目部署的处理
- site:项目站点文档创建的处理。
maven快照
痛点: 在项目的开发过程中存在下述一个问题?
当构件A依赖于构件B,但是B处于高速的迭代过程中,B的版本号的改变也造成A的版本的频繁变动,不利于维护。
解决办法:
使用 Snapshot 版本,在开发过程中B发布的版本标志为 Snapshot 版本,A进行依赖的时候选择 Snapshot 版本,那么每次B发布的话,会在私服仓库中,形成带有时间戳的 Snapshot 版本,而A构建的时候会自动下载B最新时间戳的 Snapshot 版本!
并不是每次使用都会到远程仓库获取?
- always:每次都会到远程仓库获取。
- daily:只是在第一次的时候查看是否有更新。
- interval:允许以分钟为单位的间隔时间到远程仓库区查找
- nerver:是不会去远程仓库区查找。
这些都可以在配置文件中去设置: