1. 强制版本(Highest Priority)
- 在
<dependency>
中直接指定的版本优先级最高。 - 例如:
即使其他依赖传递了不同版本,此处的<dependency> <groupId>com.example</groupId> <artifactId>example-artifact</artifactId> <version>1.0.0</version> <!-- 强制指定版本 --> </dependency>
1.0.0
会优先使用。
2. 依赖管理(Dependency Management)
- 在
<dependencyManagement>
中定义的版本优先级次高。 - 例如:
即使传递依赖有其他版本,<dependencyManagement> <dependencies> <dependency> <groupId>com.example</groupId> <artifactId>example-artifact</artifactId> <version>2.0.0</version> <!-- 通过 dependencyManagement 指定版本 --> </dependency> </dependencies> </dependencyManagement>
2.0.0
会被优先使用。
3. 父 POM 的依赖管理
- 如果项目继承了父 POM,父 POM 的
<dependencyManagement>
会覆盖子模块的依赖版本。 - 除非子模块明确指定了不同版本,否则父 POM 的版本优先级高于传递依赖。
4. 最近定义优先(Nearest Wins)
- 在依赖树中,路径最短的依赖版本优先级较高。
- 例如:
- 项目直接依赖 A 和 B。
- A 依赖 C 1.0。
- B 依赖 D,而 D 依赖 C 2.0。
- 由于 A 到 C 的路径更短,C 1.0 会被使用。
5. 最先声明优先(First Declaration Wins)
- 如果两个依赖路径长度相同,POM 文件中先声明的依赖版本优先级较高。
- 例如:
- 项目直接依赖 A 和 B。
- A 依赖 C 1.0。
- B 依赖 C 2.0。
- 如果 A 在 POM 中先声明,则 C 1.0 会被使用。
6. 传递依赖(Transitive Dependencies)
- 如果以上规则都未生效,Maven 会使用传递依赖的版本。
- 传递依赖的版本优先级最低。
7. 排除依赖(Exclusions)
- 使用
<exclusions>
可以排除特定依赖,从而间接影响优先级。 - 例如:
排除依赖后,可能会使用其他路径中的版本。<dependency> <groupId>com.example</groupId> <artifactId>example-artifact</artifactId> <version>1.0.0</version> <exclusions> <exclusion> <groupId>com.other</groupId> <artifactId>other-artifact</artifactId> </exclusion> </exclusions> </dependency>
优先级总结(从高到低)
- 强制版本(在
<dependency>
中直接指定) - 依赖管理(在
<dependencyManagement>
中指定) - 父 POM 的依赖管理
- 最近定义优先(路径最短的依赖)
- 最先声明优先(POM 中先声明的依赖)
- 传递依赖(默认的依赖版本)
- 排除依赖(通过排除间接影响优先级)
示例场景
假设有以下依赖关系:
- 项目直接依赖 A 和 B。
- A 依赖 C 1.0。
- B 依赖 C 2.0。
- 父 POM 的
<dependencyManagement>
指定 C 3.0。 - 项目中通过
<dependency>
强制指定 C 4.0。
最终优先级:
- 强制版本 C 4.0 被使用(最高优先级)。
- 如果没有强制版本,则使用依赖管理中的 C 3.0。
- 如果没有依赖管理,则使用路径最短的依赖(A 的 C 1.0 或 B 的 C 2.0)。
- 如果路径长度相同,则使用 POM 中先声明的依赖版本。