Maven之坐标和依赖

Maven之坐标和依赖_jerry_dyy的博客-CSDN博客

Maven之仓库_jerry_dyy的博客-CSDN博客

Maven之聚合与继承_jerry_dyy的博客-CSDN博客

Maven之生命周期和插件_jerry_dyy的博客-CSDN博客

坐标:

Maven依靠坐标来实现构件的唯一性。

Maven坐标元素包括:groupId、artifactId、version、packaging、classifier。

只要提供正确的坐标,Maven就可以从仓库中找到正确的构件。

groupId: 一般是域名的倒置;

artifactId: 一般以实际项目名称作为前缀,模块名作为后缀,就像:nexus-indexer,foo-core;

version: 定义版本,Maven定义了一套完整的版本规范,以及快照(SNAPSHOT)的概念;

packaging:打包方式,默认值为Jar;

classifer: 帮助定义构件输出一些附属构件,比如xxx-javadoc.jar(Java文档),xxx-sources.jar(源代码)。

其中groupId、artifactId、version是必须定义的,packaging是可选的,而classifer是不能直接定义的。

构件的文件名与坐标相对应,一般规则是:artifactId-version[-classfier].packaging。

Maven仓库的布局基于Maven坐标。

依赖:

project下的dependencies可以包含多个dependency元素。

每个dependency包含的元素有:

groupId、artifactId、version:依赖的基本坐标;

type: 依赖的类型,对应于项目坐标定义的packaging,默认值为Jar;

scope: 依赖的范围;

optional: 标记依赖是否可选;

exclusions: 用来排除传递性依赖。

依赖的范围:

三套Classpath: 编译主代码的时候需要使用一套classpath,编译和执行测试代码的时候会使用另外一套classpath,实际运行Maven项目的时候又会使用一套classpath。

依赖范围就是用来控制依赖与这三种classpath(编译classpath、测试classpath、运行classpath)的关系:

Compile: 编译依赖范围,默认使用该编译范围,对于编译、测试、运行三种classpath都有效;

Test: 测试依赖范围,只对于测试classpath有效,例如JUnit,它只有在编译测试代码以及运行测试的时候才需要;

Provided: 已提供依赖范围,对于编译和测试classpath有效,但在运行时无效,例如servlet-api;

Runtime: 运行时依赖范围,对于测试和运行classpath有效,但在编译主代码时无效,例如JDBC驱动;

System: 系统依赖范围,该依赖与三种classpath的关系,和provided一致。但是使用system依赖范围时必须通过systemPath元素显示地指定依赖文件的路径,往往与本地绑定,可能造成构件的不可移植,应该谨慎使用;

Import: 导入依赖范围,该依赖范围不会对三种classpath产生实际的影响,只有type为pom的时候,使用该依赖范围用于引入dependencyManagement。

传递性依赖:

A依赖了B,B依赖了C,那么C就是A的传递性依赖。

有了传递性依赖,Maven就会解析各个直接依赖的POM,将那些必要的间接依赖,以传递性依赖的形式引入到当前项目中。

依赖范围对传递性依赖产生影响:

最左边一列表示第一直接依赖范围,最上面一行表示第二直接依赖范围。

CompileTestProvidedRuntime
Compilecompile----runtime
Testtest----test
Providedprovided--providedprovided
Runtimeruntime----runtime

依赖调解:

第一原则:路径最近者优先:

A->B->C->X(1.0), A->D->X(2.0),两个不同版本的X,因为X(2.0)路径长度短,所以会被解析使用。

第二原则:第一声明者优先:

在路径长度相等的前提下,在POM中依赖声明的顺序决定了谁会被解析使用。A->B->Y(1.0), A->C->Y(2.0),在该例中,如果B的依赖声明在C之前,那么Y(1.0)将会被解析使用。

可选依赖:

如果路径中出现可选依赖(optional),那么依赖将不会传递了:

A>B,  B->X(可选), B->Y(可选),由于X、Y是可选依赖,依赖将不会得以传递,也就是说,X、Y将不会对A有任何影响。

最佳实践:

排除依赖:dependency中声明exclusions,exclusions中有一个或多个exclusion,exclusion中只需要groupId、artifactId即可。

归类依赖:定义properties元素,定义xxx.version,然后在需要的地方引用${xxx.version},避免出错。

优化依赖:Maven会自动解析所有项目的直接依赖和间接依赖,并根据规则正确判断每个依赖的范围,对于一些依赖冲突,也能进行调解,以确保任何一个构件只有唯一的版本在依赖中存在。在这些工作之后,得到的那些依赖被称为已解析依赖。

查看已解析依赖列表:mvn dependency:list

查看已解析依赖树:mvn dependency:tree

依赖分析:mvn dependency:analyze

可以分析那些依赖是使用到了,但是没有显示声明:当升级对应的直接依赖之后,相关的传递性依赖版本也有可能发生辩护,不易察觉,因此,最好直接声明项目中直接用到的任何依赖。

那些依赖是没有使用到,但是直接声明了的:只会分析编译主代码和测试代码需要用到的依赖,一些执行测试和运行时需要的依赖它发现不了。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值