依赖管理是maven的一个广为人知的特性, 这也是maven擅长的一个领域. 为单一的工程管理依赖不是很难, 但当你着手处理多模块工程和包含数十或数百个模块的应用时, maven可以帮助你很好地保持高度控制和稳定性.
Transitive Dependencies
依赖传递性是 maven 2.0中的一个新特性. 这不需要你去搜索和指定你自己的依赖需要的库, 而是自动地包含它们.
这个特性通过从指定的远程仓库读取你依赖的工程文件. 通常, 那些工程的所有依赖关系都会用于你的工程, 因为该项目从其父母或依赖关系中继承了这些.
没有限制依赖的组织层次数目, 但如果发现一个循环依赖就会发生问题.
由于依赖传递, 包含库的关系图会迅速变得很大. 因此, 有一些额外的特性来限制哪些依赖被包含:
(1) Dependency mediation. 依赖调解. 这决定了, 当一个构件的多个版本相遇时, 使用哪个版本的依赖. 目前, maven 2.0 只支持使用最近的定义("nearest definition"), 就是说, 它将使用在依赖树中离你的项目最近的版本. 你可以显式地在项目的pom文件中声明, 保证总是使用某个特定的版本. 注意, 如果2个依赖版本在依赖树中的深度一样, 在maven 2.0.8之前, 它没有定义哪个版本会胜出, 但从maven 2.0.9, 由声明的顺序来决定, 第一声明者优先.
nearest definition, 是指在依赖树中离你的工程最近的那个版本. 比如, 如果A,B,C之间的依赖关系为: A->B->C->D 2.0, 以及 A->E->D 1.0, 这样, 当构建A时, 将会使用 D 1.0. 因为从A到D的路径, 后者更短. 你可以显式地在A中添加一个依赖 D 2.0, 强制使用D 2.0.
(2) Dependency management. 依赖管理. 当构件在依赖传递中 或没有指定版本的依赖中相遇时, 工程作者可以直接 指定使用构件的哪个版本. 在上一节的例子中, 一个依赖会被添加到A中, 即使它不是直接被A使用. 相反, A可以在它的依赖管理中包含D作为一个依赖, 直接控制D在被引用时使用哪个版本.
(3) Dependency scope. 依赖范围. 只包含适合当前构建阶段的依赖. 下面会详细描述这一点.
(4) Excluded dependencies. 排除依赖. 如果工程X依赖工程Y, 工程Y依赖工程Z, 工程X的所有者可以显式地排除工程Z作为一个依赖, 使用 exclusion 元素 .
(5) Optional dependencies. 可选依赖. 如果工程Y依赖工程Z, 工程Y的所有者可以标记工程Z作为一个可选依赖, 使用optional标签. 当工程X依赖工程Y时, X将只依赖Y, 而不依赖Z. X的所有者也可显式地添加Z作为一个依赖. 这有助于将可选依赖理解为默认的排除依赖.