Appearance
依赖管理
5.1 依赖配置语法
Maven 的依赖配置在 POM 文件的 <dependencies> 元素中定义,每个依赖由 <dependency> 元素表示。
基本依赖配置
xml
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13.2</version>
<scope>test</scope>
</dependency>
</dependencies>依赖配置的主要元素
- groupId:依赖的组织或公司标识符
- artifactId:依赖的项目标识符
- version:依赖的版本号
- scope:依赖的范围
- type:依赖的类型,默认为 jar
- classifier:依赖的分类器
- optional:是否为可选依赖
- exclusions:排除的传递依赖
5.2 依赖范围详解
Maven 定义了多种依赖范围,用于控制依赖在不同构建阶段的可见性。
依赖范围列表
| 范围 | 编译时 | 测试时 | 运行时 | 说明 |
|---|---|---|---|---|
| compile | ✅ | ✅ | ✅ | 默认范围,在编译、测试和运行时都可用 |
| provided | ✅ | ✅ | ❌ | 只在编译和测试时可用,运行时由容器提供 |
| runtime | ❌ | ✅ | ✅ | 只在运行时可用,编译时不需要 |
| test | ❌ | ✅ | ❌ | 只在测试时可用 |
| system | ✅ | ✅ | ❌ | 与 provided 类似,但需要显式指定依赖的路径 |
| import | - | - | - | 用于依赖管理,只在 dependencyManagement 中使用 |
依赖范围示例
xml
<!-- 编译时依赖 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>5.3.20</version>
<!-- scope 默认为 compile -->
</dependency>
<!-- 编译和测试时依赖,运行时由容器提供 -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>4.0.1</version>
<scope>provided</scope>
</dependency>
<!-- 运行时依赖 -->
<dependency>
<groupId>com.mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.28</version>
<scope>runtime</scope>
</dependency>
<!-- 测试依赖 -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13.2</version>
<scope>test</scope>
</dependency>5.3 依赖传递与排除
依赖传递
Maven 支持依赖传递,当项目 A 依赖项目 B,项目 B 依赖项目 C 时,项目 A 会自动依赖项目 C。
例如:
- 项目 A 依赖项目 B
- 项目 B 依赖项目 C
- 项目 A 会自动依赖项目 C
排除传递依赖
有时我们不希望引入某些传递依赖,可以使用 <exclusions> 元素来排除。
xml
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.3.20</version>
<exclusions>
<exclusion>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
</exclusion>
</exclusions>
</dependency>5.4 依赖冲突解决
当多个依赖引入了相同库的不同版本时,会发生依赖冲突。Maven 会根据以下规则来解决冲突:
- 路径最短优先:依赖路径越短,优先级越高
- 声明顺序优先:在 POM 文件中声明较早的依赖,优先级越高
查看依赖树
使用 mvn dependency:tree 命令可以查看项目的依赖树,帮助识别依赖冲突:
bash
mvn dependency:tree解决依赖冲突的方法
- 显式声明依赖:在 POM 文件中显式声明需要的版本
- 使用 dependencyManagement:在父 POM 中统一管理依赖版本
- 排除传递依赖:使用
<exclusions>排除不需要的依赖版本
5.5 依赖版本管理
使用属性管理版本
可以使用属性来管理依赖版本,提高版本的一致性和可维护性:
xml
<properties>
<spring.version>5.3.20</spring.version>
<junit.version>4.13.2</junit.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>${junit.version}</version>
<scope>test</scope>
</dependency>
</dependencies>使用 dependencyManagement
dependencyManagement 用于统一管理依赖版本,子项目可以继承这些版本:
xml
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>5.3.20</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13.2</version>
<scope>test</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<!-- 版本从 dependencyManagement 继承 -->
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<!-- 版本和范围从 dependencyManagement 继承 -->
</dependency>
</dependencies>5.6 可选依赖与依赖优化
可选依赖
使用 <optional> 元素可以将依赖标记为可选,这样当其他项目依赖本项目时,不会自动引入这些可选依赖:
xml
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.12.0</version>
<optional>true</optional>
</dependency>依赖优化
可以使用 mvn dependency:analyze 命令来分析项目的依赖,识别未使用的依赖:
bash
mvn dependency:analyze依赖清理
使用 mvn dependency:purge-local-repository 命令可以清理本地仓库中未使用的依赖:
bash
mvn dependency:purge-local-repository通过合理的依赖管理,可以减少项目的依赖冲突,提高构建效率,确保项目的稳定性。