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

可选依赖项

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

依赖范围

可以使用如下所述的各种依赖关系范围来限制传递依赖关系发现。

先生。 范围和描述
1

编译

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

2

假如

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

3

运行

此范围表示编译不需要依赖项,但在执行过程中需要依赖项。

4

测试

此范围指示依赖项仅适用于测试编译和执行阶段。

5

系统

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

6

进口

仅当依赖项为 pom.xml 类型时才使用此范围。此范围指示指定的 POM 应替换为该 POM 的 <dependencyManagement> 部分中的依赖项。

依赖管理

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

依赖图

以下是上述依赖图的详细信息 -

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

应用程序-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>

应用程序核心库

<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>

应用程序数据库

<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>

<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 的概念将公共依赖项放置在单个位置。Root项目中列出了App-Data-libApp-Core-lib项目的依赖项(参见Root的打包类型,为POM)。

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