(二)坐标
1 构件坐标
在maven中,构件(jar、war等文件)通过坐标进行标识。其中,坐标分为项目坐标和依赖坐标。
2 项目坐标与代码目录规定
我们在开发项目时也需要为其定义坐标,这是maven强制要求的。在这个基础上,其他项目才能引用该项目生成的构件。
项目坐标通常由groupId、artifactId、version、packaging四个元素组成。其中:
groupId:定义当前maven项目隶属的实际项目
artifactId:定义实际项目中的一个maven项目
version:maven项目当前所处版本
packaging:定义maven项目的打包方式,打包方式与所生成构件的扩展名对应。当不定义packaging的时候,maven会使用默认值jar。
3 依赖坐标
每个依赖可以包含的元素包括:
(1)构件坐标:groupId、artifactId、version
(2)构件打包:type,默认值为jar
(3)依赖范围:scope,默认为compile
(4)是否可选:optional,默认为false
(5)排除传递性依赖:exclusions
其中,仅构件坐标是必填的。是否可选用于定义多个依赖,但是项目中仅仅使用其中一个依赖的情况,需要注意的是,可选依赖在传递性依赖中会被自动忽略。
4 依赖问题
4.1 依赖范围
Maven项目涉及三种classpath,其中,编译需要使用一套classpath,执行测试需要使用一套classpath,运行maven项目需要使用一套classpath。依赖范围就是用来控制依赖与编译、测试、运行的关系。常见的依赖范围有四种:
compile:作用域:编译、测试、运行(默认依赖范围)。
test:作用域:测试阶段。
provided:作用域:编译、测试。
runtime:对测试和运行有效,但编译主代码无效。作用域:测试、运行。
system:与provided完全一致,但是依赖不是通过maven仓库解析的,而是在显式指定依赖在本机的位置。
我们应该根据依赖的作用范围来决定依赖的scope。在手动写插件如make-assembly-plugin时就会得心应手。
4.2 传递性依赖
传递性依赖指的是所依赖的构件存在依赖其他构件的情况,这时,maven会解析所依赖构件所对应的各个直接依赖的POM,并将必要的间接依赖以传递性依赖的形式引入到当前的项目中。那么这时需要的是,将其他间接依赖引入到本项目中,就涉及到间接依赖在项目中的依赖范围和冲突解决的问题。
4.3 传递性依赖的依赖范围
假设A依赖于B,B依赖于C,那么,A对于B是第一直接依赖,B对于C是第二直接依赖,A对于C是传递性依赖,第一直接依赖范围和第二直接依赖范围决定了传递性依赖的依赖范围。也就是说,当项目A依赖于项目B后,会自动解析项目B的所对应的直接依赖构件C,并将C也依赖到项目A中,但是C的依赖范围由A、B共同决定。
4.4 传递性依赖冲突
有时,解析传递性依赖时存在解析到项目中的传递性依赖冲突(构件仅坐标版本不同)的情况,这时,maven本身有处理技巧:
(1)路径最优者优先
(2)路径相同冲突时以第一声明者优先
除此外,也可在依赖时通过exclusions手动去除冲突的依赖并直接依赖期望的构件。需要说明的是,去除依赖时无需说明版本,因为对应依赖中的该构件版本必然唯一。
5 maven版本号
5.1 版本号约定
maven的版本号约定是这样的:
<主版本>.<次版本>.<增量版本>-<里程碑版本>
主版本:只有当项目发生重大架构变更才会改变主版本。
次版本:表示对上一个版本进行了大范围的功能增加或功能变化或Bug修复。
增量版本:表示对上一个版本进行了小范围的Bug修复。
里程碑版本:指的是某一个版本的里程碑,带有里程碑的版本往往不稳定,说明处于开发阶段。
5.2 版本比较
当用户在声明依赖或插件未声明版本时就会按照上述的版本号约定自动解析最新版本,这时就需要对版本号排序。由于里程碑版本只可能在最后出现,因此有几种情况:
(1)都不含有里程碑版本,比较是基于数字的,2.0>1.5>1.4>1.3.11>1.3.9
(2)至少有一个含有里程碑版本,则忽略里程碑版本进行数字比较,若里程碑版本高,则说明里程碑版本高,若里程碑版本低,说明里程碑版本较低。若里程碑版本相同与其相同,则对方为纯数字把版本,则说明里程碑版本更高,若对方为里程碑版本,则进行里程碑版本部分的字符串比较,因此有:2.1.1>2.1-shat-3>2.1-shat-11>2.1。
有疑问欢迎留言