二.maven依賴管理

maven的核心功能是依賴管理和自動化構(gòu)建,我們這節(jié)講解maven的依賴管理。

1.坐標(biāo)

maven是根據(jù)坐標(biāo)來定位依賴,一般常用的是三個坐標(biāo):
groupId:一般用公司或者組織官網(wǎng)域名倒序+項目名,例如com.baidu.oa
artifactId:模塊名
version:版本號
我們使用artifactId+groupId+version坐標(biāo)來定位引用某一個依賴;如下圖,我們使用dependency標(biāo)簽引用一個spring-webmvc的jar包。引用jar包可通過maven+jar包名搜索,去maven中央倉庫尋找。

  <groupId>com.baidu.erp</groupId>
  <artifactId>erp-user</artifactId>
  <version>0.0.1-SNAPSHOT</version>
  <packaging>jar</packaging>
  <denpendencies>
    <dependency>  
        <groupId>org.springframework</groupId>  
        <artifactId>spring-webmvc</artifactId>  
        <version>3.2.8.RELEASE</version>
        <scope>compile</scope>  
    </dependency> 
  </dependencies>

此時maven會去配置的倉庫地址下載依賴。

2.依賴范圍 (依賴的使用范圍)

上圖中scope標(biāo)簽是來確定jar包的依賴范圍,scope有如下依賴范圍:
compile:默認(rèn)是compile,編譯、測試、運行都有效
test:僅僅測試有效 例如junit ,打包時減少體積
provided:編譯和測試時有效,運行時無效
runtime:測試和運行時有效,編譯時無效
system:系統(tǒng)依賴范圍,使用system范圍的依賴時必須通過systemPath元素顯示地指定依賴文件的路徑,不依賴Maven倉庫解析,所以可能會造成建構(gòu)的不可移植,謹(jǐn)慎使用。

3.依賴傳遞

maven的依賴可以通過引用來傳遞,例如project A依賴project B,那么project就可以使用project B項目的所有包,也就是project B引用的依賴都傳遞給project A,并沒有層級顯示,可以project C、D、E,多層次引用都可以傳遞給project A

4.依賴調(diào)解

如下圖項目依賴關(guān)系
A-->B--D(spring 3.2.8)
A-->C(spring1.2.8)
根據(jù)maven的依賴傳遞項目D會把spring3.2.8版本傳遞給項目A,項目C也會把spring1.2.8版本傳遞給A
此時項目A maven會自動選擇哪個版本呢?
maven根據(jù)就近原則選擇,層級路徑一樣長的時候會選擇pom.xml首先聲明的引用
此時會選擇項目C的1.2.8版本

  <groupId>com.baidu.erp</groupId>
  <artifactId>A</artifactId>
  <version>0.0.1-SNAPSHOT</version>
  <packaging>jar</packaging>
  <denpendencies>
    <dependency>  
        <groupId>com.baidu.erp</groupId>  
        <artifactId>B</artifactId>  
        <version>0.0.1-SNAPSHOT</version>
        <scope>compile</scope>  
    </dependency> 
    <dependency>  
        <groupId>com.baidu.erp</groupId>  
        <artifactId>C</artifactId>  
        <version>0.0.1-SNAPSHOT</version>
        <scope>compile</scope>  
    </dependency> 
  </dependencies>
  <groupId>com.baidu.erp</groupId>
  <artifactId>B</artifactId>
  <version>0.0.1-SNAPSHOT</version>
  <packaging>jar</packaging>
  <denpendencies>
    <dependency>  
        <groupId>com.baidu.erp</groupId>  
        <artifactId>D</artifactId>  
        <version>0.0.1-SNAPSHOT</version>
        <scope>compile</scope>  
    </dependency> 
  </dependencies>
  <groupId>com.baidu.erp</groupId>
  <artifactId>D</artifactId>
  <version>0.0.1-SNAPSHOT</version>
  <packaging>jar</packaging>
  <denpendencies>
    <dependency>  
        <groupId>org.springframework</groupId>
        <artifactId>spring-core</artifactId> 
        <artifactId></artifactId>  
        <version>3.2.8</version>
        <scope>compile</scope>  
    </dependency> 
  </dependencies>
  <groupId>com.baidu.erp</groupId>
  <artifactId>C</artifactId>
  <version>0.0.1-SNAPSHOT</version>
  <packaging>jar</packaging>
  <denpendencies>
    <dependency>  
        <groupId>org.springframework</groupId>
        <artifactId>spring-core</artifactId> 
        <artifactId></artifactId>  
        <version>1.2.8</version>
        <scope>compile</scope>  
    </dependency> 
  </dependencies>

5.可選依賴

項目B的依賴包,不想必須傳遞給項目A,那么可以在項目B的依賴包下加上<optional>true</optional>,意思是可選的,項目A可以不用

  <groupId>com.baidu.erp</groupId>
  <artifactId>B</artifactId>
  <version>0.0.1-SNAPSHOT</version>
  <packaging>jar</packaging>
  <denpendencies>
    <dependency>  
        <groupId>com.baidu.erp</groupId>  
        <artifactId>D</artifactId>  
        <version>0.0.1-SNAPSHOT</version>
       <optional>true</optional>  
    </dependency> 
  </dependencies>

這樣項目A依賴項目B的時候,可以不依賴項目D的jar包

6.依賴沖突 排除依賴

例如上面依賴選項對方?jīng)]有添加可選依賴optional或者多層依賴導(dǎo)致依賴沖突的時候,各種class not found錯誤,此時是maven根據(jù)依賴原則自動調(diào)解選擇了錯誤的版本,此時需要我們手動選擇較高版本,比如我們排除項目B的版本,不選擇這個低版本

  <groupId>com.baidu.erp</groupId>
  <artifactId>A</artifactId>
  <version>0.0.1-SNAPSHOT</version>
  <packaging>jar</packaging>
  <denpendencies>
    <dependency>  
        <groupId>com.baidu.erp</groupId>  
        <artifactId>B</artifactId>  
        <version>0.0.1-SNAPSHOT</version>
        <scope>compile</scope>  
       <exclusions>
        <exclusion>
           <groupId>org.springframework</groupId>
           <artifactId>spring-core</artifactId>
        </exclusion>
       </exclusions>
    </dependency> 
  </dependencies>

引用項目B,但是排除項目B的spring-core版本。
當(dāng)項目復(fù)雜,我們可以查看依賴樹來分析
執(zhí)行mvn dependency:tree 可以查看到詳細的依賴樹來分析

7.依賴管理

maven有三種依賴關(guān)系:依賴(上面已講解)、聚合、繼承

1.聚合

當(dāng)我們有大量模塊,手動一個個構(gòu)建就會特別不方便,此時我們可以把多個模塊聚合在一起,這樣就只需構(gòu)建一次。下面我們用父工程聚合A,B,C模塊

  <groupId>com.baidu.erp</groupId>
  <artifactId>parent</artifactId>
  <version>0.0.1-SNAPSHOT</version>
  <!-- 父工程的packaging必須為pom -->
  <packaging>pom</packaging>
    <modules>
        <module>A</module>
        <module>B</module>
        <module>C</module>
    </modules>

這是對于父工程聚合子工程,我們還需把各個子工程移動到父工程目錄下!
如果對于同級別工程<module>../A</module>那么就要用相對路徑

2.繼承

工作中,我們經(jīng)常把一個項目拆分成多個模塊,多個模塊需要的jar包又有大量重復(fù),這時我們需要一個父工程引用這些公共包,然后各模塊繼承這個父工程。
如圖父工程

  <groupId>com.baidu.erp</groupId>
  <artifactId>parent</artifactId>
  <version>0.0.1-SNAPSHOT</version>
  <!-- 父工程的packaging必須為pom -->
  <packaging>pom</packaging>
    <dependencies>
        <!-- spring依賴 -->
       <dependency>  
            <groupId>org.springframework</groupId>  
            <artifactId>spring-core</artifactId>  
            <version>3.2.8.RELEASE</version>  
        </dependency>  
        <dependency>  
            <groupId>org.springframework</groupId>  
            <artifactId>spring-webmvc</artifactId>  
            <version>3.2.8.RELEASE</version>  
        </dependency>  
    </dependencies>

如下圖子工程A繼承父工程,包含父工程依賴的jar具體版本號都會繼承過來

  <groupId>com.baidu.erp</groupId>
  <artifactId>A</artifactId>
  <version>0.0.1-SNAPSHOT</version>
  <packaging>jar</packaging>
    <parent>
        <groupId>com.zhss.parent</groupId>
        <artifactId>parent</artifactId>
        <version>0.0.1-SNAPSHOT</version>
    </parent>

當(dāng)父工程不強制子工程繼承依賴,可以選擇性使用的時候,父工程可以如下圖配置

  <groupId>com.baidu.erp</groupId>
  <artifactId>parent</artifactId>
  <version>0.0.1-SNAPSHOT</version>
  <!-- 父工程的packaging必須為pom -->
  <packaging>pom</packaging>
   <dependencyManagement>
     <!-- 子項目可選擇引用,不會自動繼承,引用后可以不用寫版本號,這里已經(jīng)強制版本號-->
    <dependencies>
        <!-- spring依賴 -->
        <dependency>  
            <groupId>org.springframework</groupId>  
            <artifactId>spring-core</artifactId>  
            <version>3.2.8.RELEASE</version>  
        </dependency>  
        <dependency>  
            <groupId>org.springframework</groupId>  
            <artifactId>spring-webmvc</artifactId>  
            <version>3.2.8.RELEASE</version>  
        </dependency>  
    </dependencies>
  </dependencyManagement>
3.使用scope import 解決單繼承問題

上面這種繼承是單繼承,和java一樣,但是工作中我們不但需要父類工程,還需要引入公共基礎(chǔ)組件,并需要使用公共基礎(chǔ)組件里提供的依賴版本號。此時maven提供了一種import的方式,此方式可以通過非繼承的方式來引入公共依賴配置

  <groupId>com.baidu.erp</groupId>
  <!-- 我們通常會把這個工程定義為bom工程 -->
  <artifactId>A-bom</artifactId>
  <version>0.0.1-SNAPSHOT</version>
  <!-- packaging必須為pom -->
  <packaging>pom</packaging>
   <dependencyManagement>
    <dependencies>
        <!-- spring依賴 -->
        <dependency>  
            <groupId>org.springframework</groupId>  
            <artifactId>spring-core</artifactId>  
            <version>3.2.8.RELEASE</version>  
        </dependency>  
        <dependency>  
            <groupId>org.springframework</groupId>  
            <artifactId>spring-webmvc</artifactId>  
            <version>3.2.8.RELEASE</version>  
        </dependency>  
    </dependencies>
  </dependencyManagement>

可以使使用如下方式引用

  <groupId>com.baidu.erp</groupId>
  <artifactId>B</artifactId>
  <version>0.0.1-SNAPSHOT</version>
  <packaging>jar</packaging>
   <dependencyManagement>
    <dependencies> 
        <dependency>  
            <groupId>com.baidu.erp</groupId>  
            <artifactId>A-bom</artifactId>
            <version>0.0.1-SNAPSHOT</version>
            <type>pom</type>
            <!-- 此時的scope import必須在dependencyManagement內(nèi) -->
            <scope>import</scope>  
        </dependency>  
    </dependencies>
  </dependencyManagement>
  <dependencies>
        <dependency>  
            <groupId>org.springframework</groupId>  
            <artifactId>spring-core</artifactId>    
          <!-- 此時和繼承父工程一樣,不需要版本號,已經(jīng)被強制約束了版本號 -->
        </dependency>  
        <dependency>  
            <groupId>org.springframework</groupId>  
            <artifactId>spring-webmvc</artifactId>    
        </dependency>
  </dependencies>
4.使用properties統(tǒng)一約定版本號
  <groupId>com.baidu.erp</groupId>
  <artifactId>A-bom</artifactId>
  <version>0.0.1-SNAPSHOT</version>
  <packaging>pom</packaging>
  <!-- 使用properties定義版本號 -->
  <properties>
     <spring.version>3.2.8.RELEASE</spring.version>
  </properties>
   <dependencyManagement>
    <dependencies>
        <!-- spring依賴 -->
        <dependency>  
            <groupId>org.springframework</groupId>  
            <artifactId>spring-core</artifactId>  
            <version>${spring.version}</version>  
        </dependency>  
        <dependency>  
            <groupId>org.springframework</groupId>  
            <artifactId>spring-webmvc</artifactId>  
            <version>${spring.version}</version>  
        </dependency>  
    </dependencies>
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • Maven在編譯,測試和運行時使用的是不同的ClassPath, 所以Maven通過dependency的scop...
    邵增衛(wèi)閱讀 409評論 0 0
  • Maven工程的拆分與聚合(重點) 一個完整的早期開發(fā)好的crm項目,現(xiàn)在要使用maven工程對它進行拆分,這時候...
  • 管理包依賴是 Maven 核心功能之一,下面通過如何引入 jar 包;如何解析 jar 包依賴;包沖突是如何產(chǎn)生;...
    data4閱讀 12,293評論 3 16
  • Maven依賴管理 其中一個Maven的核心特征是依賴管理。管理依賴關(guān)系變得困難的任務(wù)一旦我們處理多模塊項目(包含...
    木易林1閱讀 246評論 0 1
  • 問題背景 公司有個業(yè)務(wù)功能的組件,該組件以jar包的形式透出去;為了把組件的pom弄的比較干凈,一開始沒有加入任何...
    ericsonyc閱讀 305評論 0 0

友情鏈接更多精彩內(nèi)容