Maven 简明教程
Maven - Manage Dependencies
Maven 的核心功能之一是依赖项管理。一旦我们开始处理多模块项目(包含数百个模块/子项目),那么管理依赖项就会成为一项困难的任务。Maven 提供了高度的控制来管理此类场景。
Transitive Dependencies Discovery
通常一种情况是,一个库(例如 A)依赖于另一个库(例如 B)。如果另一个项目 C 要使用 A,那么该项目需要使用库 B。
Maven 帮助避免此类要求以发现所有必需的库。Maven 通过读取依赖项的项目文件 (pom.xml)、找出它们的依赖项等来做到这一点。
我们只需要在每个项目 pom 中定义直接依赖。Maven 会自动处理其余部分。
使用传递依赖项,包含的库的图形可能会迅速增长到很大程度。当出现重复库时,可能会出现这种情况。Maven 提供了一些功能来控制传递依赖项的范围。
Sr.No. |
Feature & Description |
1 |
Dependency mediation 确定当遇到某个构件的多个版本时要使用哪个版本的依赖项。如果两个依赖项版本在依赖项树中的深度相同,则将使用第一个声明的依赖项。 |
2 |
Dependency management 当依赖项以传递依赖项的形式出现时,直接指定要使用的构件的版本。对于一个示例项目,C 可以将其依赖项管理部分中的 B 包含为依赖项,并直接控制在引用它时要使用 B 的哪个版本。 |
3 |
Dependency scope 根据构建的当前阶段包含依赖项。 |
4 |
Excluded dependencies 可以使用“exclusion”元素排除任何传递依赖项。例如,A 依赖于 B,而 B 依赖于 C,那么 A 可以将 C 标记为已排除。 |
5 |
Optional dependencies 可以使用“optional”元素将任何传递依赖项标记为可选。例如,A 依赖于 B,而 B 依赖于 C。现在 B 将 C 标记为可选的。那么 A 不会使用 C。 |
Dependency Scope
可以使用各种依赖项范围来限制传递依赖项发现,如下所述。
Sr.No. |
Scope & Description |
1 |
compile 此范围表明依赖项可在项目的 classpath 中使用。它是默认范围。 |
2 |
provided 此范围表明依赖项将在运行时由 JDK 或 web 服务器/容器提供。 |
3 |
runtime 此范围表明在编译过程中不需要依赖项,但在执行过程中需要依赖项。 |
4 |
test 此范围表明依赖项仅可用于测试编译和执行阶段。 |
5 |
system 此范围表明您必须提供系统路径。 |
6 |
import 只有依赖项为 pom 类型时,才使用此范围。此范围表明应当使用该 POM 中 <dependencyManagement> 部分中的依赖项替换指定的 POM。 |
Dependency Management
通常,在通用项目下,我们有一组项目。在这种情况下,我们可以创建一个具有所有通用依赖项的通用 pom,然后将此 pom 设为子项目 pom 的父级。下面的示例将帮助你理解此概念。
以下是上述依赖项关系图的详细信息 -
-
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-lib 和 App-Core-lib 项目的依赖项在 Root 项目中列出(请参阅 Root 的打包类型。它是 POM)。
-
不必在 App-UI-WAR 中将 Lib1、lib2、Lib3 指定为依赖项。Maven 使用 Transitive Dependency Mechanism 来管理此类详细信息。