Maven - 依赖管理



Maven 的核心功能之一是依赖管理。当我们处理多模块项目(包含数百个模块/子项目)时,管理依赖是一个难题。Maven 提供了高度的控制来管理此类场景。

传递依赖发现

经常出现这种情况,一个库(例如 A)依赖于另一个库(例如 B)。如果另一个项目 C 想使用 A,则该项目也需要使用库 B。

Maven 有助于避免发现所有必需库的此类需求。Maven 通过读取依赖项的项目文件 (pom.xml) 、找出它们的依赖项等等来实现。

我们只需要在每个项目的 pom 中定义直接依赖。Maven 会自动处理其余部分。

使用传递依赖,包含的库图可能会迅速增长到很大程度。可能会出现重复库的情况。Maven 提供了一些功能来控制传递依赖的范围。

序号 功能和描述
1

依赖仲裁

确定在遇到多个版本的构件时要使用哪个版本的依赖项。如果两个依赖项版本在依赖树中处于相同的深度,则将使用第一个声明的依赖项。

2

依赖管理

直接指定在传递依赖中遇到时要使用的构件版本。例如,项目 C 可以在其依赖管理部分中包含 B 作为依赖项,并直接控制在引用 B 时要使用的 B 的版本。

3

依赖范围

根据构建的当前阶段包含依赖项。

4

排除依赖

可以使用“exclusion”元素排除任何传递依赖项。例如,A 依赖于 B,而 B 依赖于 C,则 A 可以将 C 标记为排除项。

5

可选依赖

可以使用“optional”元素将任何传递依赖项标记为可选。例如,A 依赖于 B,而 B 依赖于 C。现在 B 将 C 标记为可选。那么 A 将不会使用 C。

依赖范围

可以使用下面提到的各种依赖范围来限制传递依赖发现。

序号 范围和描述
1

compile

此范围表示依赖项在项目的类路径中可用。这是默认范围。

2

provided

此范围表示依赖项应由 JDK 或 Web 服务器/容器在运行时提供。

3

runtime

此范围表示编译不需要依赖项,但在执行期间需要。

4

test

此范围表示依赖项仅在测试编译和执行阶段可用。

5

system

此范围表示您必须提供系统路径。

6

import

此范围仅在依赖项类型为 pom 时使用。此范围表示应将指定的 POM 替换为该 POM 的``部分中的依赖项。

依赖管理

通常,我们在一个公共项目下有一组项目。在这种情况下,我们可以创建一个包含所有公共依赖项的公共 pom,然后将此 pom 作为子项目 pom 的父级。下面的示例将帮助您理解这个概念。

dependency graph

以下是上述依赖关系图的详细信息:

  • App-UI-WAR 依赖于 App-Core-lib 和 App-Data-lib。
  • Root 是 App-Core-lib 和 App-Data-lib 的父级。
  • Root 在其依赖项部分中定义 Lib1、lib2、Lib3 作为依赖项。

App-UI-WAR

<project xmlns = "http://maven.apache.org/POM/4.0.0"
   xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance"
   xsi:schemaLocation = "http://maven.apache.org/POM/4.0.0
   http://maven.apache.org/xsd/maven-4.0.0.xsd">
   <modelVersion>4.0.0</modelVersion>
   <groupId>com.companyname.groupname</groupId>
   <artifactId>App-UI-WAR</artifactId>
   <version>1.0</version>
   <packaging>war</packaging>
   <dependencies>
      <dependency>
         <groupId>com.companyname.groupname</groupId>
         <artifactId>App-Core-lib</artifactId>
         <version>1.0</version>
      </dependency>
   </dependencies>  
   <dependencies>
      <dependency>
         <groupId>com.companyname.groupname</groupId>
         <artifactId>App-Data-lib</artifactId>
         <version>1.0</version>
      </dependency>
   </dependencies>  
</project>

App-Core-lib

<project xmlns = "http://maven.apache.org/POM/4.0.0"
   xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance"
   xsi:schemaLocation = "http://maven.apache.org/POM/4.0.0
   http://maven.apache.org/xsd/maven-4.0.0.xsd">
   <parent>
      <artifactId>Root</artifactId>
      <groupId>com.companyname.groupname</groupId>
      <version>1.0</version>
   </parent>
   <modelVersion>4.0.0</modelVersion>
   <groupId>com.companyname.groupname</groupId>
   <artifactId>App-Core-lib</artifactId>
   <version>1.0</version> 
   <packaging>jar</packaging>
</project>

App-Data-lib

<project xmlns = "http://maven.apache.org/POM/4.0.0"
   xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance"
   xsi:schemaLocation = "http://maven.apache.org/POM/4.0.0
   http://maven.apache.org/xsd/maven-4.0.0.xsd">
   <parent>
      <artifactId>Root</artifactId>
      <groupId>com.companyname.groupname</groupId>
      <version>1.0</version>
   </parent>
   <modelVersion>4.0.0</modelVersion>
   <groupId>com.companyname.groupname</groupId>
   <artifactId>App-Data-lib</artifactId>
   <version>1.0</version>   
   <packaging>jar</packaging>
</project>

Root

<project xmlns = "http://maven.apache.org/POM/4.0.0"
   xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance"
   xsi:schemaLocation = "http://maven.apache.org/POM/4.0.0
   http://maven.apache.org/xsd/maven-4.0.0.xsd">
   <modelVersion>4.0.0</modelVersion>
   <groupId>com.companyname.groupname</groupId>
   <artifactId>Root</artifactId>
   <version>1.0</version>
   <packaging>pom</packaging>
   <dependencies>
      <dependency>
         <groupId>com.companyname.groupname1</groupId>
         <artifactId>Lib1</artifactId>
         <version>1.0</version>
      </dependency>
   </dependencies>  
   <dependencies>
      <dependency>
         <groupId>com.companyname.groupname2</groupId>
         <artifactId>Lib2</artifactId>
         <version>2.1</version>
      </dependency>
   </dependencies>  
   <dependencies>
      <dependency>
         <groupId>com.companyname.groupname3</groupId>
         <artifactId>Lib3</artifactId>
         <version>1.1</version>
      </dependency>
   </dependencies>  
</project>

现在,当我们构建 App-UI-WAR 项目时,Maven 将通过遍历依赖关系图来发现所有依赖项并构建应用程序。

从上面的示例中,我们可以学习以下关键概念:

  • 可以使用父 pom 的概念将公共依赖项放在单个位置。App-Data-libApp-Core-lib 项目的依赖项列在 Root 项目中(参见 Root 的打包类型。它是 POM)。

  • 无需在 App-UI-WAR 中指定 Lib1、lib2、Lib3 作为依赖项。Maven 使用传递依赖机制来管理此类细节。

广告