Maven依賴管理


其中一個Maven的核心特徵是依賴管理。管理依賴關係變得困難的任務一旦我們處理多模組專案(包含數百個模組/子專案)。 Maven提供了一個高程度的控制來管理這樣的場景。

傳遞依賴發現

這是很通常情況下,當一個庫說A就依賴於其他庫說B的情況下,另一個專案Ç想用A,則該專案需要使用庫中B。

在Maven幫助下以避免這樣的要求來發現所有需要的庫。 Maven通過讀取依賴項專案檔案(pom.xml中),找出它們的依賴等。

我們只需要在每個專案POM定義直接依賴關係。 Maven自動處理其餘部分。

傳遞依賴,包括庫的圖形可能會快速增長在很大程度上。可能出現情況下,當有重複的庫。 Maven提供一些功能來控制傳遞依賴程度

Feature 描述
Dependency mediation Determines what version of a dependency is to be used when multiple versions of an artifact are encountered. If two dependency versions are at the same depth in the dependency tree, the first declared dependency will be used.
Dependency management Directly specify the versions of artifacts to be used when they are encountered in transitive dependencies. For an example project C can include B as a dependency in its dependencyManagement section and directly control which version of B is to be used when it is ever referenced.
Dependency scope Includes dependencies as per the current stage of the build
Excluded dependencies Any transitive dependency can be excluede using "exclusion" element. As example, A depends upon B and B depends upon C then A can mark C as excluded.
Optional dependencies Any transitive dependency can be marked as optional using "optional" element. As example, A depends upon B and B depends upon C. Now B marked C as optional. Then A will not use C.

依賴範圍

傳遞依賴發現可以使用各種依賴範圍如下文所述受到限制

Scope 描述
compile This scope indicates that dependency is available in classpath of project. It is default scope.
provided This scope indicates that dependency is to be provided by JDK or web-Server/Container at runtime.
runtime This scope indicates that dependency is not required for compilation, but is required during execution.
test This scope indicates that the dependency is only available for the test compilation and execution phases.
system This scope indicates that you have to provide the system path.
import This scope is only used when dependency is of type pom. This scopes indicates that the specified POM should be replaced with the dependencies in that POM's <dependencyManagement> section.

依賴關係管理

通常情況下,我們已經一套專案在一個共同的專案下。在這種情況下,我們可以創造讓所有的公共依賴一個共同的POM,然後進行分專案POMS為這個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-lib 和 App-Core-lib 專案列表在 Root 目錄(見Roots包型別。它是POM).

  • 不需要Lib1, lib2, Lib3 作為依賴於 App-UI-WAR. Maven使用傳遞性依賴機制來管理這些細節。