1. 程式人生 > >一點一點學maven(07)——maven依賴(範圍、傳遞、排除、衝突)

一點一點學maven(07)——maven依賴(範圍、傳遞、排除、衝突)

1、依賴範圍

依賴範圍由<dependency></dependency>標籤中<scope></scope>標籤來定義。

專案如果要使用某個框架或依賴,需要把相關jar包引用到classpath中,maven專案提供了三個classpath:編譯、測試、執行。

依賴的範圍用於控制依賴於三種classpath關係的,包括:compile、provided、runtime、test、system、import

   compile:預設範圍,編譯、測試、執行都有效
   provided:編譯和測試有效,最後執行不會被加入,如tomcat依賴
   runtime:在測試和執行的時候有效,編譯不會被加入,比如jdbc驅動jar
   test:測試階段有效,比如junit
   system:與provided一致,編譯和測試階段有效,但與系統關聯,可移植性差
   import:匯入的範圍,它只是用在dependencyManagement中,表示從其它的pom中匯入dependency的配置

例如:

<dependency>
      <groupIdjunit</groupId>
      <artifactId>junit</artifactId>
      <version>3.8.1</version>
      <!-- 只在測試階段使用該依賴 -->
      <scope>test</scope>
</dependency>
        <!-- 只在編譯、測試期有效,在執行期無效,執行期使用tomcat容器自己的jar包 -->
<!-- servlet support --> <dependency> <groupId>javax.servlet</groupId> <artifactId>javax.servlet-api</artifactId> <version>3.0.1</version> <scope>provided</scope> </dependency
>
<!-- jsp support --> <dependency> <groupId>javax.servlet.jsp</groupId> <artifactId>jsp-api</artifactId> <version>2.1</version> <scope>provided</scope> </dependency>

2、依賴傳遞

比如:A專案依賴B,B專案依賴C,此時C專案就會傳遞到A專案中。

C專案:

  <groupId>com.jsun.test</groupId>
  <artifactId>C</artifactId>
  <version>0.0.1-SNAPSHOT</version>

B專案:

    <dependency>
      <groupId>com.jsun.test</groupId>
      <artifactId>C</artifactId>
      <version>0.0.1-SNAPSHOT</version>
    </dependency>

A專案:

    <dependency>
      <groupId>com.jsun.test</groupId>
      <artifactId>B</artifactId>
      <version>0.0.1-SNAPSHOT</version>
    </dependency>

檢視專案maven依賴列表,如圖:
這裡寫圖片描述

C專案自動被引入到A專案中,這就是依賴傳遞的結果。

3、依賴排除

如果此時,A專案依賴B專案,無需依賴C專案,那麼需要把自動傳遞的依賴排除掉,通過<exclusions>標籤實現。
A專案引用B專案依賴時,主動排除傳遞的C專案依賴,修改A專案pom.xml
程式碼:

<dependency>
      <groupId>com.jsun.test</groupId>
      <artifactId>B</artifactId>
      <version>0.0.1-SNAPSHOT</version>
      <exclusions>
        <exclusion>
          <groupId>com.jsun.test</groupId>
          <artifactId>C</artifactId>
        </exclusion>
      </exclusions>
    </dependency>

還可以通過,C專案被B專案引用時,主動禁止自己被傳遞,只在B專案中使用,通過<optional>true</optional>實現,修改B專案的pom.xml:

    <dependency>
      <groupId>com.mavan.demo</groupId>
      <artifactId>C</artifactId>
      <version>0.0.1-SNAPSHOT</version>
      <optional>true</optional>
    </dependency>

效果如圖:
這裡寫圖片描述

A專案的maven依賴列表中只有B專案,而C專案自動被排除了。


補充:如果想把當前依賴的所有傳遞依賴排除掉,可以使用萬用字元*

<dependency>
      <groupId>com.jsun.test</groupId>
      <artifactId>B</artifactId>
      <version>0.0.1-SNAPSHOT</version>
      <exclusions>
        <exclusion>
          <groupId>*</groupId>
          <artifactId>*</artifactId>
        </exclusion>
      </exclusions>
    </dependency>

4、依賴衝突

依賴引用有兩個原則:

1)、短路優先原則:優先引用路徑短的依賴
比如現在有兩個依賴路徑:(1)A–>B–>C–>X.1,(2)A–>B–>X.2,則(2)路徑被優先解析,A專案使用X的版本為X.2版本。

比如A專案依賴B專案,B專案依賴C專案,B專案依賴commons-io的2.4版本,C專案依賴commons-io的2.0版本,則A專案的maven依賴列表中出現的是commons-io的2.4版本:
B專案:

    <dependency>
        <groupId>commons-io</groupId>
        <artifactId>commons-io</artifactId>
        <version>2.4</version>
    </dependency>

C專案:

    <dependency>
        <groupId>commons-io</groupId>
        <artifactId>commons-io</artifactId>
        <version>2.0</version>
    </dependency>

maven依賴列表如圖:

這裡寫圖片描述

2)、路徑相同,先宣告優先原則

比如,A專案依賴B專案,A專案依賴C專案,B、C專案分別依賴commons-io的2.4和2.0版本,A專案引用B、C依賴時,C引用放在B前面,則A使用的是commons-io的2.0版本。

B專案:

    <dependency>
        <groupId>commons-io</groupId>
        <artifactId>commons-io</artifactId>
        <version>2.4</version>
    </dependency>

C專案:

    <dependency>
        <groupId>commons-io</groupId>
        <artifactId>commons-io</artifactId>
        <version>2.0</version>
    </dependency>

A專案:

    <dependency>
      <groupId>com.jsun.test</groupId>
      <artifactId>C</artifactId>
      <version>0.0.1-SNAPSHOT</version>
    </dependency>
    <dependency>
      <groupId>com.jsun.test</groupId>
      <artifactId>B</artifactId>
      <version>0.0.1-SNAPSHOT</version>
    </dependency>

檢視A專案maven依賴列表,如圖:

這裡寫圖片描述