Maven管理依赖关系


Maven的核心功能之一是依赖管理。一旦我们需要处理多模块项目(由数百个模块/子项目组成),管理依赖关系是一项艰巨的任务。Maven提供高度的控制来管理这些场景。

传递依赖关系发现

通常情况下,当一个图书馆(比如说A)依赖于其他图书馆,比如说B时。如果另一个项目C想要使用A,那么该项目也需要使用图书馆B.

Maven有助于避免这样的需求来发现所有需要的库。Maven通过读取依赖关系的项目文件(pom.xml),找出它们的依赖关系等等。

我们只需要在每个项目中定义直接依赖关系。Maven自动处理剩下的部分。

通过传递依赖关系,包含库的图形可以在很大程度上快速增长。存在重复库时可能会出现这种情况。Maven提供了一些功能来控制传递依赖的程度。

序号 功能和说明
1 依赖调解
确定在遇到多个版本的工件时要使用哪个版本的依赖关系。如果两个依赖版本在依赖关系树中处于相同深度,则将使用第一个声明的依赖关系。
2 依赖管理
直接指定在传递依赖关系中遇到的工件的版本。举一个例子,项目C可以在其依赖关系管理部分中包含B作为依赖关系,并直接控制何时引用B的哪个版本。
3 依赖范围
按照构建的当前阶段包含依赖项。
4 排除的依赖关系
任何传递依赖可以使用“排除”元素排除。例如,A取决于B而B取决于C,那么A可以将C标记为排除。
5 可选的依赖关系
使用“可选”元素可将任何传递依赖项标记为可选项。例如,A取决于B,而B取决于C.现在B将C标记为可选。那么A不会使用C.

依赖范围

传递性依赖关系发现可以使用各种依赖性范围进行限制,如下所述。

序号 范围和说明
1 compile
这个范围表示依赖项在项目的类路径中可用。它是默认范围。
2 provided
此范围表示依赖性将在运行时由JDK或web-Server / Container提供。
3 runtime
该范围表示编译时不需要依赖关系,但在执行期间需要。
4 test
此范围表示依赖项仅适用于测试编译和执行阶段。
5 system
此范围表示您必须提供系统路径。
6 import
该范围仅在依赖类型为pom时使用。此范围表示应将指定的POM替换为该POM的 dependencyManagement部分中的依赖项。

依赖管理

通常,我们在一个共同的项目下有一套项目。在这种情况下,我们可以创建一个具有所有通用依赖关系的通用pom,然后创建这个pom,即子项目的poms的父项。下面的例子将帮助你理解这个概念。

依赖关系图

以下是上述依赖图的细节 -

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

应用核-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>

针对应用的数据,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>

<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使用 Transitive Dependency Mechanism 来管理这些细节。