三沣开发知识 购物 网址 游戏 小说 歌词 地图 快照 开发 股票 美女 新闻 笑话 | 汉字 软件 日历 阅读 下载 图书馆 编程 China
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
vbs/VBScript DOS/BAT hta htc python perl 游戏相关 VBA 远程脚本 ColdFusion ruby专题
autoit seraphzone PowerShell linux shell Lua Golang Erlang 其它教程 CSS/HTML/Xhtml
html5 CSS XML/XSLT Dreamweaver教程 经验交流 开发者乐园 Android开发资料
站长资讯 .NET新手 ASP.NET C# WinForm Silverlight WCF CLR WPF XNA VisualStudio ASP.NET-MVC .NET控件开发 EntityFramework WinRT-Metro Java C++ PHP Delphi Python Ruby C语言 Erlang Go Swift Scala R语言 Verilog 其它语言 架构设计 面向对象 设计模式 领域驱动 Html-Css JavaScript jQuery HTML5 SharePoint GIS技术 SAP OracleERP DynamicsCRM K2 BPM 信息安全 企业信息 Android开发 iOS开发 WindowsPhone WindowsMobile 其他手机 敏捷开发 项目管理 软件工程 SQLServer Oracle MySQL NoSQL 其它数据库 Windows7 WindowsServer Linux
  IT知识库 -> 敏捷开发 -> Maven依赖解析 -> 正文阅读
 

[敏捷开发]Maven依赖解析

Maven依赖解析  本文将记录Maven工程中依赖解析机制,内容包括:
Maven依赖基本结构 从仓库解析依赖的机制 依赖传递性解析实例 1. Maven依赖基本结构
上篇文章记录了Maven依赖的聚合与继承,POM中依赖的声明通过dependency进行定义,并且通过groupId、artifactId及version三项定位Maven库中的唯一依赖。除了这三项外,还有其他属性进行限制,如下:

 1 <dependencies>
 2    <dependency>
 3      <groupId>...</groupId>
 4      <artifactId>...</artifactId>
 5      <version>...</version>
 6      <type>...</type>
 7      <scope>...</scope>
 8      <optional>...</optional>
 9      <exclusions>
10         <exclusion>
11             <groupId>...</groupId>
12             <artifactId>...</artifactId>
13         </exclusion>
14      </exclusions>
15    </dependency>
16 </dependencies>

groupId、artifactId及version三项不再叙说; type:依赖类型,对应于项目坐标定义的packaging,默认为jar; scope:依赖范围,包括compile、test、runtime、import、provided、system; optional:标记依赖为可选,即依赖没有传递性; exclusions:排除传递性依赖 1.1 依赖范围
  我们知道,Maven工程约定具有固定的目录结构,以便于Maven各插件对工程处理,如编译(compile)插件,会将src/main/java中的类编译到target/classes目录下,则编译对应的classpath即为target/classes。依赖范围就是控制依赖于编译classpath(target/classes)、测试classpath(target/test-classes)和运行classpath(以Web工程为例,WEB-INF/classes)的关系。具体依赖范围的讲述可参考官网文档,在此仅进行稍微总结:
compile:编译依赖范围,对编译、测试、运行classpath都有效,为默认范围; test:测试依赖范围,仅对测试classpath有效; runtime:运行时依赖范围,对测试和运行classpath有效,对编译无效,如JDBC的依赖引入,因为JDK中值声明了JDBC接口,具体实现由各厂家决定; import:导入依赖范围,对三种classpath不产生实际影响,一般是导入pom类型的依赖,聚合情况下需要声明打包类型为pom,其中可包含dependencyManagement(如上一篇文章),此时对引入该依赖的工程不产生影响; provided:已提供依赖范围,对测试和编译classpath有效,对运行时无效,如servlet-api在测试或编译的时候需要,在运行的时候由容器提供,故不需要重复引入; system:系统依赖范围,与provided范围一致,需要明确指定该jar包,其不在Maven仓库中,感觉不太常用。 1.2 依赖传递性
依赖传递性,举例说明,比如A引用B,B引用C,正常情况下,A也会引用C依赖,即A经过传递间接引用了C(依赖为可选时,需另行处理)。具体不同范围的依赖经过传递后,其依赖范围的变化如下边(从官网扣下来的)

依赖传递的准则:
路径最近这优先,即在引用传递链上,获取出离本POM最近的传递性依赖; 如果路径距离相同,则以取POM中的声明顺序靠前的。 1.3 可选依赖
   可选依赖不被传递。假设项目A依赖于B,B依赖于X和Y,并且X和Y声明为可选,则X和Y对A就不具有传递性了。如果A需要依赖于X或Y,则需要直接引用。
1.4 依赖排除
   假设项目A依赖于B,B依赖于C(版本为1.0),此时A会传递性依赖于C(1.0)。如果A需要引用C(2.0版本),存在两种情况:
  (1)A直接引用C(2.0),则可以不对B依赖添加exclusions元素;
  (2)A在引用B的同时,还引用D(D引用C(2.0)),则可以在引用B的时候使用exclusions元素将C(1.0)排除,也可以将D依赖声明在B之前。
2. 从仓库解析依赖的机制
   依赖解析的基本过程:当本地仓库中没有依赖构件,则Maven从远程仓库中下载;当依赖版本为快照版本时,Maven会自动计算最新的快照,并引用。
  背后的依赖解析机制概括如下:
  (1)当依赖的范围为system,则从本机文件系统中解析构件;
  (2)根据依赖坐标计算定位依赖位置后,尝试从本地仓库寻找依赖,若找到,则解析成功;
  (3)若本地仓库没有对应构件,则遍历所有远程仓库,发现后解析下载;
  (4)如果依赖的版本为RELEASE或LATEST,则读取所有远程仓库的元数据groupId/artifactId/version/maven-metadata.xml,与本地元数据合并后,计算出RELEASE或LATEST的真实值,然后基于真实值检查本地仓库和远程仓库,如步骤(2)(3);
  (5)如果依赖的版本为SNAPSHOT,类似的,读取远程仓库的元数据,并与本地元数据合并,计算出最新版本的快照,再从本地仓库和远程仓库检索。
 下边为一个快照版本依赖的元数据maven-metadata-local.xml,包括最近更新时间戳,以及存在的不同版本:

<?xml version="1.0" encoding="UTF-8"?>
<metadata>
  <groupId>com.test</groupId>
  <artifactId>C</artifactId>
  <versioning>
    <versions>
      <version>1.0-SNAPSHOT</version>
      <version>2.0-SNAPSHOT</version>
    </versions>
    <lastUpdated>20171113125841</lastUpdated>
  </versioning>
</metadata>

 对应文件目录结构如下:

3. 依赖传递性解析实例
   创建3个Maven工程A、B、C(命令mvn archetype:generate)。
  (1)编辑各自的POM文件,使其依赖关系如下图所示:
                    

其中B为A的直接依赖,C具有传递性,为A的传递性依赖,分析其依赖树可以直观的看出依赖关系(mvn dependency:tree),如下:
B依赖于C(1.0)

 A依赖于B(1.0),间接依赖C(1.0)

(2)将B对的C的依赖改为optional,即可选的,此时A的依赖树如下,不包括C:

(3)修改POM文件,使其依赖关系如下:
          

 看A的依赖树,如下:

 综上,正常情况下依赖是具有传递性,除非声明为optional。
总结: 声明依赖时,除了常用的三项位置元素,还具有包括范围、类型、可选和排除等; 依赖具有传递性,具有路径优先的约定; 当引用多个工程时,会潜在的引用其他依赖,需要注意是否会引错包,或者冲突; Maven依赖解析,对于本地库中没有的构件,Maven会综合远程仓库与本地仓库的元数据,计算最新版本后,再引用。 参考:
Introduction to the Dependency Mechanism
《Maven实践》
  敏捷开发 最新文章
Git~分支真的很轻
分享一个开源免费、目前最好的API接口管理平
论「版本号」的正确使用方式
GitLab~当它是一个源代码管理工具时
Maven依赖解析
如何基于 eolinker 的进行接口管理
Docker与CI持续集成/CD
需求工程的基本过程
信息系统实践手记3
如何打造百亿级数据处理量的弹性调度容器平
上一篇文章           查看所有文章
加:2017-11-17 23:31:22  更:2017-11-17 23:31:24 
 
技术频道: 站长资讯 .NET新手区 ASP.NET C# WinForm Silverlight WCF CLR WPF XNA Visual Studio ASP.NET MVC .NET控件开发 Entity Framework WinRT/Metro Java C++ PHP Delphi Python Ruby C语言 Erlang Go Swift Scala R语言 Verilog 其它语言 架构设计 面向对象 设计模式 领域驱动设计 Html/Css JavaScript jQuery HTML5 SharePoint GIS技术 SAP Oracle ERP Dynamics CRM K2 BPM 信息安全 企业信息化其他 Android开发 iOS开发 Windows Phone Windows Mobile 其他手机开发 敏捷开发 项目与团队管理 软件工程其他 SQL Server Oracle MySQL NoSQL 其它数据库 Windows 7 Windows Server Linux
脚本语言: vbs/VBScript DOS/BAT hta htc python perl 游戏相关 VBA 远程脚本 ColdFusion ruby专题 autoit seraphzone PowerShell linux shell Lua Golang Erlang 其它教程
网站开发: CSS/HTML/Xhtml html5 CSS XML/XSLT Dreamweaver教程 经验交流 开发者乐园 Android开发资料
360图书馆 软件开发资料 文字转语音 购物精选 软件下载 美食菜谱 新闻资讯 电影视频 小游戏 Chinese Culture 股票 租车
生肖星座 三丰软件 视频 开发 短信 中国文化 网文精选 搜图网 美图 阅读网 多播 租车 短信 看图 日历 万年历 2018年7日历
2018-7-22 22:41:23
多播视频美女直播
↓电视,电影,美女直播,迅雷资源↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT知识库