Skip to content

依赖管理

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 会根据以下规则来解决冲突:

  1. 路径最短优先:依赖路径越短,优先级越高
  2. 声明顺序优先:在 POM 文件中声明较早的依赖,优先级越高

查看依赖树

使用 mvn dependency:tree 命令可以查看项目的依赖树,帮助识别依赖冲突:

bash
mvn dependency:tree

解决依赖冲突的方法

  1. 显式声明依赖:在 POM 文件中显式声明需要的版本
  2. 使用 dependencyManagement:在父 POM 中统一管理依赖版本
  3. 排除传递依赖:使用 <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

通过合理的依赖管理,可以减少项目的依赖冲突,提高构建效率,确保项目的稳定性。