依赖管理
# 依赖管理
# 依赖配置
依赖指当前项目运行所需的 jar,一个项目可以设置多个依赖格式。
# 依赖传递
# 依赖具有传递性
- 直接依赖:在当前项目中通过依赖配置建立的依赖关系
- 间接依赖:被依赖的资源如果依赖其他资源,当前项目间接依赖其他资源
# 依赖传递冲突问题
- 路径优先:当依赖中出现相同的资源时,层级越深,优先级越低,层级越浅,优先级越高(项目依赖树中的位置决定)
- 声明优先:当资源在相同层级被依赖时,配置顺序靠前的覆盖配置顺序在后的(前覆盖后)
- 特殊优先:当同级配置了相同资源的不同版本,后配置的覆盖先配置的(不同版本,后覆盖前)
# 可选依赖
对外隐藏当前所依赖的资源 -- 不透明
可选依赖(Optional Dependency)是一种依赖管理策略,用于指示某些依赖项不是强制性的,或者在编译时不是必须的,但在运行时可能需要。
这种依赖类型通常用于以下情况:
- 当你的项目依赖于一个库,但只有在某些特定条件下才会使用它。
- 当你想提供向后兼容性,允许使用旧版本的库,但同时支持新版本的功能。
在 Java 的 Maven 构建工具中,可以使用 <optional>
标签来定义可选依赖。
以下是一个 Maven pom.xml
文件中的示例:
<project>
<!-- ... 其他配置 ... -->
<dependencies>
<!-- 必需的依赖项 -->
<dependency>
<groupId>com.example</groupId>
<artifactId>core-lib</artifactId>
<version>1.0.0</version>
</dependency>
<!-- 可选的依赖项 -->
<dependency>
<groupId>com.example</groupId>
<artifactId>optional-lib</artifactId>
<version>2.0.0</version>
<!-- true 默认为 false 不隐藏, 为 true 则对外隐藏 -->
<optional>true</optional>
</dependency>
<!-- ... 其他依赖项 ... -->
</dependencies>
<!-- ... 其他配置 ... -->
</project>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
在这个示例中,optional-lib
被标记为可选依赖。这意味着:
- Maven 在构建过程中不会自动将这个依赖项传递给其他依赖这个项目的项目。
- 这个依赖项仅在当前项目中需要时才被包含。
# 排除依赖
主动断开依赖的资源,被排除的资源无需指定版本 -- 不需要 exclusions
(标签)
# 依赖范围
依赖的 jar 默认情况可以在任何地方使用, 可以通过 <scope>
标签设定其作用范围。
- compile(默认):
- 编译依赖是默认范围,适用于所有阶段:编译、测试和运行。如果你不指定依赖范围,它将使用
compile
范围。
- 编译依赖是默认范围,适用于所有阶段:编译、测试和运行。如果你不指定依赖范围,它将使用
- provided:
- 提供的依赖范围意味着这些依赖项在编译和测试阶段是必需的,但在运行时,它们应该由 JDK 或运行环境(如Java EE容器)提供。因此,这些依赖项不会被包含在最终的打包文件中。
- runtime:
- 运行时依赖范围的依赖项在运行和测试阶段是必需的,但在编译阶段不是必需的。这意味着这些依赖项会被包含在最终的打包文件中,但不会包含在编译时的类路径中。
- test:
- 测试依赖范围的依赖项仅在测试阶段有效,它们对于编译主代码或运行应用程序是不必要的。这些依赖项不会被包含在最终的打包文件中。
- system:
- 系统依赖范围的依赖项需要从指定的系统路径中获取,而不是从 Maven 仓库中获取。这种方式不推荐使用,因为它降低了项目的可移植性。使用
system
范围时,必须提供<systemPath>
标签,指向依赖项的本地路径。
- 系统依赖范围的依赖项需要从指定的系统路径中获取,而不是从 Maven 仓库中获取。这种方式不推荐使用,因为它降低了项目的可移植性。使用
- import:
- 导入依赖范围用于在子项目中引入父项目中
<dependencyManagement>
部分定义的依赖项。这允许子项目继承父项目的依赖项版本和配置,而不必直接复制依赖项声明。
- 导入依赖范围用于在子项目中引入父项目中
- optional:
- 可选依赖范围允许某个依赖项声明为可选的,这意味着其他依赖项可以选择包含或排除这个可选依赖。可选依赖项在编译和测试阶段是可用的,但在运行时可能不可用。
- 注意:
- 依赖范围的继承性:除了
test
和provided
范围之外,其他范围的依赖项默认会继承到子模块中。test
范围的依赖项不会传递到子模块,而provided
范围的依赖项在运行时也不会传递。
- 依赖范围的继承性:除了
示例:
<project>
<!-- ... 其他配置 ... -->
<dependencies>
<!-- 编译依赖 -->
<dependency>
<groupId>com.example</groupId>
<artifactId>compile-dep</artifactId>
<version>1.0.0</version>
<scope>compile</scope>
</dependency>
<!-- 已提供依赖 -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>4.0.1</version>
<scope>provided</scope>
</dependency>
<!-- 运行时依赖 -->
<dependency>
<groupId>com.example</groupId>
<artifactId>runtime-dep</artifactId>
<version>2.0.0</version>
<scope>runtime</scope>
</dependency>
<!-- 测试依赖 -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13.2</version>
<scope>test</scope>
</dependency>
<!-- 系统依赖 -->
<dependency>
<groupId>com.example</groupId>
<artifactId>system-dep</artifactId>
<version>1.0.0</version>
<scope>system</scope>
<systemPath>/path/to/system-dep.jar</systemPath>
</dependency>
<!-- ... 其他依赖项 ... -->
</dependencies>
<!-- ... 其他配置 ... -->
</project>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
上次更新: 2024/12/26 17:53:41