- 浏览: 796661 次
- 性别:
- 来自: 上海
文章分类
- 全部博客 (651)
- Java (39)
- Java 初学者小问题 (66)
- 设计模式 (7)
- 项目管理 (3)
- 数据库 (1)
- 算法 (2)
- Java practices (6)
- Effective Java2读书笔记 (78)
- Linux (2)
- programming ruby 读书笔记 (5)
- Core Java Ninth Edition Volume I 读书笔记 (15)
- Pro Git 读书笔记 (12)
- Git (3)
- Maven in Action 读书笔记 (20)
- Web (12)
- 非技术类书籍 (11)
- 电影 (40)
- Web Cache (1)
- jquery (0)
- 历史 (4)
- Dive Into HTML5 读书笔记 (13)
- 三国演义小学毕业考 (79)
- 高效能人士的7个习惯 读书笔记 (12)
- Java Performance 读书笔记 (3)
- Protocol Buffer 学习笔记 (6)
- Mongo DB 学习笔记 (7)
- Morphia 学习笔记 (7)
- Algorithms -- Princeton 学习笔记 (13)
- String研究 (10)
- Hadoop: The Definitive Guide 读书笔记 (3)
- Java与模式读书笔记 (5)
- Date研究 (3)
- The Roman Empire 听课笔记 (4)
- Algorithms -- Standford 学习笔记 (16)
- Core Java Ninth Edition Volume II 读书笔记 (9)
- Thinking in Java 4th Edition 读书笔记 (21)
- Node : Up and Running 学习笔记 (5)
- Eloquent Javascript (8)
- Smashing Node.js 读书笔记 (1)
- Algorithms II -- Standford 学习笔记 (19)
- Algorithm II -- Princeton 学习笔记 (14)
- 网络安全 (2)
- Javascript (4)
- 正则表达式 (1)
- JAVA 7/8 (15)
- JVM (10)
- NodeJS (1)
- 鸟哥的linux私房菜读书笔记 (14)
- Web Service (1)
- The art of programming (9)
- Introduction to Algorithm 读书笔记 (4)
- Java 源码阅读 (0)
- Spring in Action 读书笔记 (2)
- Java Network Programming 读书笔记 (2)
最新评论
-
心存高远:
谢谢作者分享,刚好看到这里不太明白,现在茅塞顿开。不过runt ...
关于 Maven的传递依赖的理解 -
sxlkk:
851228082 写道甚至在某次技术会议现场遇到《Maven ...
关于 Maven的传递依赖的理解 -
851228082:
851228082 写道a----compile----b-- ...
第五章 坐标和依赖 -
851228082:
a----compile----b-----provided- ...
第五章 坐标和依赖 -
851228082:
甚至在某次技术会议现场遇到《Maven in action》的 ...
关于 Maven的传递依赖的理解
今天又回顾了一下 《Maven in Action》的读书笔记第五章 : http://seanzhou.iteye.com/admin/blogs/1290558。再次看到这张Maven 传递依赖的表格:
假设 A 依赖 B , B 依赖 C ,我们称 A 对 B 是第一直接依赖, B 对 C 是第二直接依赖, A 对 C 是传递依赖。下表显示了三者的关系:
第一 第二 |
compile |
test |
provided |
runtime |
compile |
compile |
- |
- |
runtime |
test |
test |
- |
- |
test |
provided |
provided |
- |
provided |
provided |
runtime |
runtime |
- |
- |
runtime |
当时就对这张表格有点一知半解,向同事和老鸟请教,大都无法对其进行解释,甚至在某次技术会议现场遇到《Maven in action》的作者Juven,向其讨教,他也一时无法解释。
如今在Maven项目上实践了这么久,又对这张表有了新的理解。首先,我觉得所谓A对B有依赖,是指A对B的artifact有依赖,也就是依赖的是B的binary。其次依赖范围决定了A对B在什么时间段具有依赖。一共有三种时间段:a)在编译源代码时 b) 在编译测试代码及运行测试用例时 c) 在运行时
四种依赖范围分别表示了在不同的时间段具有依赖:
1)compile: a) & b) & c)
2)test : b)
3)provided: a) & b)
4) runtime: c)
可见test与runtime是最弱的依赖,其次是provided,然后再是compile。下面我们来看传递依赖,我们换个角度,先不从依赖范围来看传递依赖,而是从依赖的时间段来看传递依赖。
第二 第一 |
a) | b) | c) |
a) | - | - | - |
b) | - | - | b) |
c) | - | - | c) |
解释一下,第一列表示A对B的依赖时间段,第二列表示B对C的依赖时间段。首先,如果 A对B是在编译时依赖,那A对C一定没有依赖,因为编译源代码时只需要B的binary即可通过编译,B的依赖都不会需要。所以第二行都为没有依赖。其次如果B对C为编译时依赖,因为之前说过A对B的依赖都是指A对B的binary的依赖,B无需重新编译源代码,所以第二列都为没有依赖。同样的如果B对C为编译和运行测试代码时依赖,因为无论A只对B的binary有依赖(主代码),与B的测试代码没有关系,所以第三列也都为没有依赖。所以现在只剩下表格中最后一列的最后两格需要解释了:
1. A对B在编译及执行测试代码时有依赖,而B对C在主代码运行时有依赖
对编译A的测试代码来说,A只需要B的binary,一定对C没有依赖,但对执行A的测试代码来说,执行时需要调用到B代码,而这时对B来说这是它的主代码的运行时,它对C是有依赖的。所以A对C也就有了依赖(A运行测试代码时对C有依赖)
2. A对B主代码运行时有依赖,而B对C在主代码运行时有依赖
同理,在运行A的主代码时,A需要调用B的主代码,而这时也是B的主代码的运行时,所以B需要调用C。所以A对C也有了依赖(A运行主代码时对C有依赖)。
下面我们来看依赖范围,我们将依赖范围的这张传递依赖表转换成,依赖时间段的传递依赖表:
第一 第二 |
a)&b)&c) |
b) |
a)&b) |
c) |
a)&b)&c) |
b)&c) |
- |
- |
b)&c) |
b) |
b) |
- |
- |
b) |
a)&b) |
b) |
- |
- |
b) |
c) |
c) |
- |
- |
c) |
我们来对比一下原表:
1) compile + compile --> compile, 而我们这里推出的是 b) & c),因为没有一个特定范围对应 b) & c)所以用compile来代替是合理的。
2) compile + provided -->无依赖也是合理的,但有一点必须注意,provided这个范围是比较特殊的,它并不是说在运行时没有依赖,而是说运行时的依赖会由运行环境提供,这点对传递依赖很重要。对于compile + provided的情况,我们必须保证在A的测试环境中C已经存在了 ,不然是会有问题的。因为B假定C在B的运行时已经存在了。比如说 C是servelt api,在deploy B到一个servlet container中时,C会由container提供,但在A的测试和运行环境中,必须也保证C已经存在(特别是A的测试环境)不然就有可能出现runtime exception。
3) compile + runtime --> runtime, 这点有些不合理,这会导致,在A的测试代码运行时,它调用B,而B需要调用C,这时会出现runtime excpetion。(所以我推导出的是 b) & c) ) 我持着怀疑的态度特地在Maven 3.03上验证了一下,确实compile + runtime --> runtime。所以这里我们就要特别小心了,如果A的测试代码运行时,有可能需要间接调用到C,你需要显示声明C为A的compile依赖。 (因为默认是runtime依赖,加上test依赖就是compile依赖)
4)provided + compile --> provided , 这个是很有问题的,首先, A对C在编译时肯定是不需要的(有B的binary就足够编译了)。所以我们推出的是c),也就是只在测试时需要(运行测试代码时需要)。但有一点我们需要多思考一下的,A对B是provided依赖,表明在A的主代码运行时B已经被环境提供了,A在运行时是依赖B的,而B对C是compile依赖,也就是B在运行时对C有依赖,也就是说A在运行时其实是间接依赖C的,而如果A的运行时环境提供了B,没理由不提供B的运行时依赖C, 所以这里最后得到的是provided(因为test无法表示运行时的依赖性)。
5)provided + provided --> provided,虽然我推导出的是无依赖,但由于provided的特殊性,provided并不能简单用 a) & b)来表示,其实在运行时是有依赖的,只是依赖由环境提供。首先A对C肯定在编译时是没有依赖的,但在运行测试代码时是有依赖的,因为B对C是provided依赖,也就是说C由B的运行环境提供,所以在A的测试环境需要提供C。和上节同样的道理,A的运行环境提供了B,没道理不提供B的运行时依赖C(B项目也假定了在其运行时会由环境提供C)所以是provided依赖。
6) provided + runtime --> provided,这点其实得provided + compile --> provided同理。
OK, 这样原先的大部分疑惑都已经解决了,回过头来看一下,主要是provided这个范围比较搞,它并不表示在运行时没有依赖,只是表明依赖会由运行时环境提供,但问题是如何预先知道项目的运行时环境,项目的运行时环境是会变化的。因为如果A在运行时依赖B,A的运行时环境就成了B的运行时环境可能会与原先单独运行B的环境不同。感觉Maven的这一设计有些许问题。
评论
作者自己都不知道?!!! 我也是醉了
哈哈
作者自己都不知道?!!! 我也是醉了
compile+provided => provided,而非无依赖
发表评论
-
《Maven in Action》读后感
2012-02-23 23:48 2210今天终于读完了《Maven in Action》一书,真所谓书 ... -
第十八章 Archetype
2012-02-23 23:30 50831. Archetype 是 Maven ... -
第十七章 编写Maven插件
2012-02-23 19:42 44921. 编写 Maven 插件的主要步骤 ... -
第十六章 m2eclipse
2012-02-23 15:44 23771. m2eclipse ( http: ... -
第十五章 生成项目站点
2012-02-21 09:27 22881. Maven 社区提供了大量插件,能让用户 ... -
第十四章 灵活的构建
2012-02-20 16:21 18701. 通过 <propertie ... -
第十三章 版本管理
2012-02-20 15:57 21201. 版本管理( Version Manage ... -
第十二章 使用Maven构建Web应用
2012-02-15 18:38 60411. Web 项目的 POM ... -
第十一章 使用Hudson进行持续集成
2012-02-09 17:09 23171. 持续集成就是快速 且高频率 ... -
第十章 使用Maven进行测试
2012-02-05 22:17 214111. com.google.code. ... -
第九章 使用Nexus创建私服
2011-12-06 23:17 108051. Nexus 分为开源版和企业版,开源 ... -
第八章 聚合与继承
2011-12-06 09:55 20491. 为了能用一条命令来构建一个实际 ... -
第七章 生命周期和插件
2011-12-05 13:36 23081. Maven 的生命周期就是为了对所有的构 ... -
第六章 仓库
2011-12-03 18:44 24081. Maven 在一个工作站上的某个位置统一 ... -
第五章 坐标和依赖
2011-12-03 15:14 20851. Maven 定义了这样一组规则:世界上任 ... -
第四章 背景案例
2011-12-02 21:20 14231. 主要场景: 1) 用户访问注册页面 2) ... -
第三章 Maven 使用入门
2011-12-01 18:40 25501. 就像Make的Makefile, Ant的build. ... -
第二章 Maven的安装和配置
2011-12-01 10:01 62411. 设置JAVA_HOME, Path中加入%JAVA_H ... -
第一章 Maven 简介
2011-12-01 09:48 22901. Maven 是优秀的构建工 ...
相关推荐
**一、Maven传递依赖** 传递依赖是指在Maven项目中,当一个项目A依赖于另一个项目B,而项目B又依赖于项目C时,项目A间接地依赖于项目C。这种关系使得A可以通过B来间接获取到C的类和资源。但是,并非所有的传递依赖...
Maven是Apache软件基金会的一个项目,用于项目对象模型(Project Object Model)的管理和构建自动化。...通过合理地使用POM文件、依赖范围、依赖调解和传递性依赖等机制,我们可以更好地构建和维护我们的Maven项目。
Maven的依赖机制遵循“传递性”原则,这意味着如果你的项目依赖A,而A又依赖B,那么Maven会自动将B也引入到你的项目中。但是,这可能导致版本冲突,因此Maven提供了`exclusions`标签来排除不需要的依赖。 在进行...
Maven依赖管理遵循“传递性”原则,即如果你的项目依赖A库,而A库又依赖B库,Maven会自动将B库也一并引入。这大大简化了项目的构建过程,但同时也可能导致依赖冲突,需要通过排除机制或调整依赖版本来解决。 在`...
Maven依赖管理遵循“传递性”原则,即项目可以直接依赖其他项目,间接依赖也会被自动引入。当出现相同类路径的冲突时,Maven会遵循“第一声明者优先”原则,即先声明的依赖版本优先。 2. **排除依赖(Exclusions)...
2. **理解依赖传递性**:Maven会自动处理依赖的依赖,但可能会导致依赖冲突,需要通过 `<exclusions>` 标签排除不需要的子依赖。 3. **管理本地仓库**:定期清理无用的旧版本依赖,避免仓库过大影响性能。 4. **使用...
根据提供的文件信息,我们可以了解到这是一个基于Maven构建的Web服务客户端项目。该POM(Project Object Model)...通过对这些依赖的详细了解,可以帮助开发者更好地理解和维护项目,同时也有助于进一步扩展项目功能。
此外,Maven的传递性依赖管理意味着,如果一个项目依赖A库,而A库又依赖B库,Maven会自动处理B库的下载,无需开发者手动介入。 在压缩包子文件的文件名称列表中提到的"org",这很可能是Maven依赖的组织...
Maven依赖传递特性 Maven会自动处理项目的依赖及其依赖的依赖,称为依赖传递。 2. Maven依赖冲突特性 当不同依赖引入了相同但不同版本的库时,会产生依赖冲突。Maven遵循“nearest wins”原则解决冲突,但可能需要...
总的来说,理解并掌握Maven的本地仓库和依赖管理对于JavaWeb开发者至关重要,它能够简化项目构建过程,提高开发效率,并确保项目的一致性和可重复性。通过正确配置Maven和IDEA,你可以更轻松地管理和利用这些依赖,...
本文将深入探讨"Maven中scope test的使用以及依赖继承传递"这一主题,帮助开发者更好地理解和应用Maven的核心特性。 首先,`scope test`是Maven依赖管理中的一个关键概念。当我们在`pom.xml`文件中为某个依赖设置`...
它会自动下载这些依赖及其传递性依赖到本地仓库,避免了手动管理jar文件的困扰。 3. **坐标**:在Maven中,每个项目都有唯一的坐标,由groupId、artifactId和version组成。例如,`com.example:my-app:1.0.0`,其中`...
此外,Maven的依赖管理遵循“传递性依赖”原则,即如果项目A依赖于B,B又依赖于C,那么在构建项目A时,Maven会同时下载B和C。 Maven的生命周期是另一个关键特性,它定义了一系列构建阶段,如编译、测试、打包、部署...
1. **依赖树查看**:MavenHelper提供了一个直观的依赖树视图,列出项目的所有依赖,包括直接依赖和传递依赖。你可以轻松查找特定的依赖并查看其版本信息。 2. **冲突检测**:该插件能自动检测出有版本冲突的依赖,...
Maven的依赖管理解决了版本冲突问题,通过设定依赖的传递性、范围(compile、runtime、test等)和排除机制,可以有效地管理项目间的依赖关系。 6. **聚合与继承** Maven的聚合项目可以将多个子项目组合在一起,...
总的来说,解决Maven依赖冲突需要理解其工作原理,结合IDEA提供的工具,如Maven Helper插件和依赖结构图,可以有效地定位和排除冲突,保持项目的稳定性和可维护性。在实际开发中,避免引入不必要的依赖和定期清理...
3. **依赖管理**:3.5.2增强了依赖解析机制,能更准确地处理传递性依赖,避免了版本冲突。 4. **错误修复**:此版本修复了多个已知问题,提升了Maven的稳定性和可靠性。 要下载Maven的历史版本,可以访问Apache ...