Maven 依賴關系

項目的依賴關系主要分為三種:依賴,繼承,聚合

依賴關系

依賴關系是最常用的一種,就是你的項目需要依賴其他項目,比如Apache-common包,Spring包等等。


<dependency>
       <groupId>junit</groupId>
       <artifactId>junit</artifactId>
       <version>4.11</version>
       <scope>test</scope>
       <type >jar</ type >
       <optional >true</ optional >
 </dependency>

任意一個外部依賴說明包含如下幾個要素:groupId, artifactId, version, scope, type, optional。其中前3個是必須的。
這里的version可以用區間表達式來表示,比如(2.0,)表示>2.0,[2.0,3.0)表示2.0<=ver<3.0;多個條件之間用逗號分隔,比如[1,3],[5,7]。
type 一般在pom引用依賴時候出現,其他時候不用。

maven認為,程序對外部的依賴會隨著程序的所處階段和應用場景而變化,所以maven中的依賴關系有作用域(scope)的限制。在maven中,scope包含如下的取值:

Scope選項 描述
compile(編譯范圍) compile是默認的范圍;如果沒有提供一個范圍,那該依賴的范圍就是編譯范圍。編譯范圍依賴在所有的classpath中可用,同時它們也會被打包。
provided(已提供范圍) provided依賴只有在當JDK或者一個容器已提供該依賴之后才使用。例如,如果你開發了一個web應用,你可能在編譯classpath中需要可用 的Servlet API來編譯一個servlet,但是你不會想要在打包好的WAR中包含這個Servlet API;這個Servlet API JAR由你的應用服務器或者servlet容器提供。已提供范圍的依賴在編譯classpath(不是運行時)可用。它們不是傳遞性的,也不會被打包。
runtime(運行時范圍) runtime依賴在運行和測試系統的時候需要,但在編譯的時候不需要。比如,你可能在編譯的時候只需要JDBC API JAR,而只有在運行的時候才需要JDBC驅動實現
test(測試范圍) test范圍依賴在編譯和運行時都不需要,它們只有在測試編譯和測試運行階段可用。
system(系統范圍) system范圍依賴與provided類似,但是你必須顯式的提供一個對于本地系統中JAR文件的路徑。這么做是為了允許基于本地對象編譯,而這些對象是系統類庫的一部分。這樣的構件應該是一直可用的,Maven也不會在倉庫中去尋找它。 如果你將一個依賴范圍設置成系統范圍,你必須同時提供一個systemPath元素 。注意該范圍是不推薦使用的(應該一直盡量去從公共或定制的Maven倉庫中引用依賴)。

dependency中的type一般不用配置,默認是jar。當type為pom時,代表引用關系:
此時,本項目會將persistence-deps的所有jar包導入依賴庫。

可以創建一個打包方式為pom項目來將某些通用的依賴歸在一起,供其他項目直接引用,不要忘了指定依賴類型為pom(<type>pom</type>)。

繼承關系

繼承就是避免重復,maven的繼承也是這樣,它還有一個好處就是讓項目更加安全。項目之間存在上下級關系時就屬于繼承關系。

父項目的配置如下:


<project>  
      <modelVersion>4.0.0</modelVersion>  
      <groupId>org.clf.parent</groupId>  
      <artifactId>my-parent</artifactId>  
      <version>2.0</version>  
      <packaging>pom</packaging> 
      
      <!-- 該節點下的依賴會被子項目自動全部繼承 -->
      <dependencies>
        <dependency>
               <groupId>org.slf4j</groupId>
               <artifactId>slf4j-api</artifactId>
               <version>1.7.7</version>
               <type>jar</type>
               <scope>compile</scope>
        </dependency>
      </dependencies>
      
      <dependencyManagement>
        <!-- 該節點下的依賴關系只是為了統一版本號,不會被子項目自動繼承,-->
        <!--除非子項目主動引用,好處是子項目可以不用寫版本號 -->
        <dependencies>
           <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-orm</artifactId>
                <version>4.2.5.RELEASE</version>
            </dependency>
 
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-web</artifactId>
                <version>4.2.5.RELEASE</version>
            </dependency>
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-context-support</artifactId>
                <version>4.2.5.RELEASE</version>
            </dependency>
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-beans</artifactId>
                <version>4.2.5.RELEASE</version>
            </dependency>
        </dependencies>
       </dependencyManagement>
 
       <!-- 這個元素和dependencyManagement相類似,它是用來進行插件管理的-->
       <pluginManagement>  
       ......
       </pluginManagement>
</project>

注意,此時<packaging>必須為pom

為了項目的正確運行,必須讓所有的子項目使用依賴項的統一版本,必須確保應用的各個項目的依賴項和版本一致,才能保證測試的和發布是相同的結果。

Maven 使用dependencyManagement 元素來提供了一種管理依賴版本號的方式。通常會在一個組織或者項目的最頂層的父POM 中看到dependencyManagement 元素。使用pom.xml 中的dependencyManagement 元素能讓所有在子項目中引用一個依賴而不用顯式的列出版本號。Maven 會沿著父子層次向上走,直到找到一個擁有dependencyManagement元素的項目,然后它就會使用在這個dependencyManagement 元素中指定的版本號。

父項目在dependencies聲明的依賴,子項目會從全部自動地繼承。而父項目在dependencyManagement里只是聲明依賴,并不實現引入,因此子項目需要顯示的聲明需要用的依賴。如果不在子項目中聲明依賴,是不會從父項目中繼承下來的;只有在子項目中寫了該依賴項,并且沒有指定具體版本,才會從父項目中繼承該項,并且version和scope都讀取自父pom另外如果子項目中指定了版本號,那么會使用子項目中指定的jar版本。

如果某個項目需要繼承該父項目,基礎配置應該這樣:

<project>  
      <modelVersion>4.0.0</modelVersion>  
      <groupId>org.clf.parent.son</groupId>  
      <artifactId>my-son</artifactId>  
      <version>1.0</version> 
      <!-- 聲明將父項目的坐標 -->
      <parent>
          <groupId>org.clf.parent</groupId>  
          <artifactId>my-parent</artifactId>  
          <version>2.0</version>  
          <!-- 父項目的pom.xml文件的相對路徑。相對路徑允許你選擇一個不同的路徑。 -->
          <!--  默認值是../pom.xml。Maven首先在構建當前項目的地方尋找父項目的pom, -->
          <!--  其次在文件系統的這個位置(relativePath位置), -->
          <!--  然后在本地倉庫,最后在遠程倉庫尋找父項目的pom。 -->
          <relativePath>../parent-project/pom.xml</relativePath>
      </parent> 
      
      <!-- 聲明父項目dependencyManagement的依賴,不用寫版本號 -->
      <dependencies>
          <dependency>
              <groupId>org.springframework</groupId>
              <artifactId>spring-web</artifactId>
          </dependency>
          <dependency>
              <groupId>org.springframework</groupId>
              <artifactId>spring-beans</artifactId>
          </dependency>
      </dependencies>
</project>

聚合關系

隨著技術的飛速發展和各類用戶對軟件的要求越來越高,軟件本身也變得越來越復雜,然后軟件設計人員開始采用各種方式進行開發,于是就有了我們的分層架構、分模塊開發,來提高代碼的清晰和重用。針對于這一特性,maven也給予了相應的配置。

maven的多模塊管理也是非常強大的。一般來說,maven要求同一個工程的所有模塊都放置到同一個目錄下,每一個子目錄代表一個模塊,比如

總項目/
? |--- pom.xml 總項目的pom配置文件
? |--- 子模塊1/
?? |--- pom.xml 子模塊1的pom文件
? |--- 子模塊2/
?? |--- pom.xml子模塊2的pom文件
總項目的配置如下:

<project> 
       <modelVersion>4.0.0</modelVersion> 
       <groupId>org.clf.parent</groupId> 
       <artifactId>my-parent</artifactId> 
       <version>2.0</version> 
       
       <!-- 打包類型必須為pom -->
       <packaging>pom</packaging>
       
       <!-- 聲明了該項目的直接子模塊 -->
       <modules>
       <!-- 這里配置的不是artifactId,而是這個模塊的目錄名稱-->
        <module>module-1</module>
        <module>module-2</module>
        <module>module-3</module>
    </modules>
       
       <!-- 聚合也屬于父子關系,總項目中的dependencies與dependencyManagement、pluginManagement用法與繼承關系類似 -->
       <dependencies>
        ......
       </dependencies>
        
       <dependencyManagement>
        ......
       </dependencyManagement>
 
       <pluginManagement> 
       ......
       </pluginManagement>
</project>

子模塊的配置如下:


<project> 
       <modelVersion>4.0.0</modelVersion> 
       <groupId>org.clf.parent.son</groupId> 
       <artifactId>my-son</artifactId> 
       <version>1.0</version>
       <!-- 聲明將父項目的坐標 -->
       <parent>
              <groupId>org.clf.parent</groupId> 
              <artifactId>my-parent</artifactId> 
              <version>2.0</version> 
       </parent>
</project>

繼承與聚合的關系

首先,繼承與聚合都屬于父子關系,并且,聚合 POM與繼承關系中的父POM的packaging都是pom。

不同的是,對于聚合模塊來說,它知道有哪些被聚合的模塊,但那些被聚合的模塊不知道這個聚合模塊的存在。對于繼承關系的父 POM來說,它不知道有哪些子模塊繼承與它,但那些子模塊都必須知道自己的父 POM是什么。

在實際項目中,一個 POM往往既是聚合POM,又是父 POM,它繼承了某個項目,本身包含幾個子模塊,同時肯定會存在普通的依賴關系,就是說,依賴、繼承、聚合這三種關系是并存的。

Maven可繼承的POM 元素列表如下:

groupId :項目組 ID ,項目坐標的核心元素;

version :項目版本,項目坐標的核心元素;

description :項目的描述信息;

organization :項目的組織信息;

inceptionYear :項目的創始年份;

url :項目的 url 地址

develoers :項目的開發者信息;

contributors :項目的貢獻者信息;

distributionManagerment:項目的部署信息;

issueManagement :缺陷跟蹤系統信息;

ciManagement :項目的持續繼承信息;

scm :項目的版本控制信息;

mailingListserv :項目的郵件列表信息;

properties :自定義的 Maven 屬性;

dependencies :項目的依賴配置;

dependencyManagement:醒目的依賴管理配置;

repositories :項目的倉庫配置;

build :包括項目的源碼目錄配置、輸出目錄配置、插件配置、插件管理配置等;

reporting :包括項目的報告輸出目錄配置、報告插件配置等。

?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • Spring Cloud為開發人員提供了快速構建分布式系統中一些常見模式的工具(例如配置管理,服務發現,斷路器,智...
    卡卡羅2017閱讀 134,869評論 18 139
  • 簡介 概述 Maven 是一個項目管理和整合工具 Maven 為開發者提供了一套完整的構建生命周期框架 Maven...
    閩越布衣閱讀 4,326評論 6 39
  • Spring Boot 參考指南 介紹 轉載自:https://www.gitbook.com/book/qbgb...
    毛宇鵬閱讀 46,941評論 6 342
  • 前言什么是 POMQuick Overview POM 常用元素 pom.xml 完整注釋 參考 0 前言 什么是...
    阿父閱讀 12,655評論 1 36
  • 今天上科學課我們學做不倒翁。首先老師給我們做了一次。我們一看,在牙簽旁邊綁一個繩加螺母,再加一點透明膠就可...
    火煋哥美猴王閱讀 359評論 1 3