【maven3學習之六】maven中的依賴機制簡介

依賴管理是maven的一大特徵,對於一個簡單的項目,對依賴的管理並非什麼困難的事,可是若是這個項目依賴的庫文件達到幾十個甚至於上百個的時候就不是一個簡單的問題了。在這個時候maven對於依賴管理的做用就顯露出來了。下面主要討論幾個方面的內容:傳遞性依賴,依賴範圍,依賴管理,系統依賴,可選依賴
 
傳遞性依賴:
  傳遞性依賴是在maven2中添加的新特徵,這個特徵的做用就是你不須要考慮你依賴的庫文件所須要依賴的庫文件,可以將依賴模塊的依賴自動的引入。例如咱們依賴於spring的庫文件,可是spring自己也有依賴,若是沒有傳遞性依賴那就須要咱們瞭解spring項目依賴,而後也要添加到咱們的項目中。
  因爲沒有限制依賴的數量,若是出現循環依賴的時候會出現問題,這個時候有兩種方式處理,一種是經過build-helper-maven-plugin插件來規避,另外一種就是重構兩個相互依賴的項目。
  經過傳遞性依賴,項目的依賴結構可以很快生成。可是由於這個新的特性會有一些其餘的特性被添加進來來限制因爲傳遞性依賴所引入的包。
  依賴調節:若是在一個項目裏面出現不一樣的模塊,依賴了一個項目的不一樣版本的時候判斷依賴的版本。maven2.0的時候僅僅支持最近原則也就是在依賴樹中的最靠近項目的版本做爲依賴版本。到了maven2.0.9的時候又提出了一個最早聲明原則,也就是在項目中被最先聲明的被判斷爲依賴的版本。
  依賴管理:在傳遞性依賴或者沒有指定版本的依賴的狀況下,判定依賴的版本。
  依賴範圍:決定依賴在構建的那個階段起做用。
  排除依賴:在標籤中能夠明確的排除某個依賴。
  可選依賴:標籤這個依賴是可選的。
 
依賴範圍
  maven有三套classpath(編譯classpath,運行classpath,測試classpath)分別對應構建的三個階段。依賴範圍就是控制依賴與這三套classpath的關係。依賴範圍有六種:
  compile:編譯依賴範圍,在三個classpath都有效。
  test:測試依賴範圍,在編譯代碼和運行代碼是無效。
  provided:以提供的依賴範圍,在編譯和測試的時候有效,在運行的時候無效。例如servlet-api,由於容器已經提供,在運行的時候是不須要的。
  runtime:運行時依賴範圍,僅在測試和運行的時候有效。例如jdbc只有在測試和運行的時候纔有效。
  system:系統依賴範圍,與provided範圍一致,可是依賴是經過系統變量來指定依賴,不利於移植。
  import(在maven2.0.9後支持):導入依賴範圍,對三個classpath沒有實際影響。
 
  依賴範圍影響傳遞性依賴。假如a依賴於b,b依賴於c,那麼第一個爲第一個依賴,第二個爲第二依賴。左邊第一列是第一依賴,第一行是第二依賴。
  compile provided runtime test
compile compile - runtime -
provided provided - provided -
runtime runtime - runtime -
test test - test -
 
依賴管理
  依賴管理是一個集中的依賴信息的一種方式。它能夠提供一個將依賴信息放置在一個公共的POM中讓子POM繼承。可是它只是起到限制的做用並不會引入實際依賴。
  下面提供兩個例子
 
   A項目
 1: <project>
 2:   ...
 3:   <dependencies>
 4:     <dependency>
 5:       <groupId>group-a</groupId>
 6:       <artifactId>artifact-a</artifactId>
 7:       <version>1.0</version>
 8:       <exclusions>
 9:         <exclusion>
 10:           <groupId>group-c</groupId>
 11:           <artifactId>excluded-artifact</artifactId>
 12:         </exclusion>
 13:       </exclusions>
 14:     </dependency>
 15:     <dependency>
 16:       <groupId>group-a</groupId>
 17:       <artifactId>artifact-b</artifactId>
 18:       <version>1.0</version>
 19:       <type>bar</type>
 20:       <scope>runtime</scope>
 21:     </dependency>
 22:   </dependencies>
 23: </project>
   B項目
 1: <project>
 2:   ...
 3:   <dependencies>
 4:     <dependency>
 5:       <groupId>group-c</groupId>
 6:       <artifactId>artifact-b</artifactId>
 7:       <version>1.0</version>
 8:       <type>war</type>
 9:       <scope>runtime</scope>
 10:     </dependency>
 11:     <dependency>
 12:       <groupId>group-a</groupId>
 13:       <artifactId>artifact-b</artifactId>
 14:       <version>1.0</version>
 15:       <type>bar</type>
 16:       <scope>runtime</scope>
 17:     </dependency>
 18:   </dependencies>
 19: </project>
  能夠這兩個pom裏面有公共依賴,能夠提到一個公共的父類POM中
 1: <project>
 2:   ...
 3:   <dependencyManagement>
 4:     <dependencies>
 5:       <dependency>
 6:         <groupId>group-a</groupId>
 7:         <artifactId>artifact-a</artifactId>
 8:         <version>1.0</version>
 9: 
 10:         <exclusions>
 11:           <exclusion>
 12:             <groupId>group-c</groupId>
 13:             <artifactId>excluded-artifact</artifactId>
 14:           </exclusion>
 15:         </exclusions>
 16: 
 17:       </dependency>
 18: 
 19:       <dependency>
 20:         <groupId>group-c</groupId>
 21:         <artifactId>artifact-b</artifactId>
 22:         <version>1.0</version>
 23:         <type>war</type>
 24:         <scope>runtime</scope>
 25:       </dependency>
 26: 
 27:       <dependency>
 28:         <groupId>group-a</groupId>
 29:         <artifactId>artifact-b</artifactId>
 30:         <version>1.0</version>
 31:         <type>bar</type>
 32:         <scope>runtime</scope>
 33:       </dependency>
 34:     </dependencies>
 35:   </dependencyManagement>
 36: </project>

經過這種作法,項目A和項目B的POM文件能夠被簡化java

項目Amysql

 1: <project>
 2:   ...
 3:   <dependencies>
 4:     <dependency>
 5:       <groupId>group-a</groupId>
 6:       <artifactId>artifact-a</artifactId>
 7:     </dependency>
 8: 
 9:     <dependency>
 10:       <groupId>group-a</groupId>
 11:       <artifactId>artifact-b</artifactId>
 12:       <!-- This is not a jar dependency, so we must specify type. -->
 13:       <type>bar</type>
 14:     </dependency>
 15:   </dependencies>
 16: </project>

項目Bspring

 1: <project>
 2:   ...
 3:   <dependencies>
 4:     <dependency>
 5:       <groupId>group-c</groupId>
 6:       <artifactId>artifact-b</artifactId>
 7:       <!-- This is not a jar dependency, so we must specify type. -->
 8:       <type>war</type>
 9:     </dependency>
 10: 
 11:     <dependency>
 12:       <groupId>group-a</groupId>
 13:       <artifactId>artifact-b</artifactId>
 14:       <!-- This is not a jar dependency, so we must specify type. -->
 15:       <type>bar</type>
 16:     </dependency>
 17:   </dependencies>
 18: </project>

下面的例子是對於傳遞性依賴中版本控制sql

項目A數據庫

 1: <project>
 2:  <modelVersion>4.0.0</modelVersion>
 3:  <groupId>maven</groupId>
 4:  <artifactId>A</artifactId>
 5:  <packaging>pom</packaging>
 6:  <name>A</name>
 7:  <version>1.0</version>
 8:  <dependencyManagement>
 9:    <dependencies>
 10:      <dependency>
 11:        <groupId>test</groupId>
 12:        <artifactId>a</artifactId>
 13:        <version>1.2</version>
 14:      </dependency>
 15:      <dependency>
 16:        <groupId>test</groupId>
 17:        <artifactId>b</artifactId>
 18:        <version>1.0</version>
 19:        <scope>compile</scope>
 20:      </dependency>
 21:      <dependency>
 22:        <groupId>test</groupId>
 23:        <artifactId>c</artifactId>
 24:        <version>1.0</version>
 25:        <scope>compile</scope>
 26:      </dependency>
 27:      <dependency>
 28:        <groupId>test</groupId>
 29:        <artifactId>d</artifactId>
 30:        <version>1.2</version>
 31:      </dependency>
 32:    </dependencies>
 33:  </dependencyManagement>
 34: </project>

項目Bapi

 1: <project>
 2:   <parent>
 3:     <artifactId>A</artifactId>
 4:     <groupId>maven</groupId>
 5:     <version>1.0</version>
 6:   </parent>
 7:   <modelVersion>4.0.0</modelVersion>
 8:   <groupId>maven</groupId>
 9:   <artifactId>B</artifactId>
 10:   <packaging>pom</packaging>
 11:   <name>B</name>
 12:   <version>1.0</version>
 13:   <dependencyManagement>
 14:     <dependencies>
 15:       <dependency>
 16:         <groupId>test</groupId>
 17:         <artifactId>d</artifactId>
 18:         <version>1.0</version>
 19:       </dependency>
 20:     </dependencies>
 21:   </dependencyManagement>
 22:   <dependencies>
 23:     <dependency>
 24:       <groupId>test</groupId>
 25:       <artifactId>a</artifactId>
 26:       <version>1.0</version>
 27:       <scope>runtime</scope>
 28:     </dependency>
 29:     <dependency>
 30:       <groupId>test</groupId>
 31:       <artifactId>c</artifactId>
 32:       <scope>runtime</scope>
 33:     </dependency>
 34:   </dependencies>
 35: </project>

當運行項目B的時候,a,b,c,d都是version1.0。oracle

首先a,c被顯式的聲明,而後是b在parent中的依賴管理中設定。而後是d雖然在parent中有可是在本項目中也有定義,本項目優先於父項目,全部也是version1.0。app

導入依賴maven

  這個特性是在maven2.0.9中被添加的。在上面的例子中提供了一種經過繼承的方式來管理依賴。下面提供一種導入的方式來引入依賴管理。經過設定scope爲import來實現。ide

項目B

 1: <project>
 2:   <modelVersion>4.0.0</modelVersion>
 3:   <groupId>maven</groupId>
 4:   <artifactId>B</artifactId>
 5:   <packaging>pom</packaging>
 6:   <name>B</name>
 7:   <version>1.0</version>
 8:   <dependencyManagement>
 9:     <dependencies>
 10:       <dependency>
 11:         <groupId>maven</groupId>
 12:         <artifactId>A</artifactId>
 13:         <version>1.0</version>
 14:         <type>pom</type>
 15:         <scope>import</scope>
 16:       </dependency>
 17:       <dependency>
 18:         <groupId>test</groupId>
 19:         <artifactId>d</artifactId>
 20:         <version>1.0</version>
 21:       </dependency>
 22:     </dependencies>
 23:   </dependencyManagement>
 24:   <dependencies>
 25:     <dependency>
 26:       <groupId>test</groupId>
 27:       <artifactId>a</artifactId>
 28:       <version>1.0</version>
 29:       <scope>runtime</scope>
 30:     </dependency>
 31:     <dependency>
 32:       <groupId>test</groupId>
 33:       <artifactId>c</artifactId>
 34:       <scope>runtime</scope>
 35:     </dependency>
 36:   </dependencies>
 37: </project>
咱們假設項目A就是上面給出的那個。他們最終的結果是同樣的。全部項目A的POM的依賴管理都會被合併到項目B的xml中除了d。由於在B的POM中已經有了d。
下面咱們給出一個導入兩個項目的時的例子。
X項目
 1: <project>
 2:  <modelVersion>4.0.0</modelVersion>
 3:  <groupId>maven</groupId>
 4:  <artifactId>X</artifactId>
 5:  <packaging>pom</packaging>
 6:  <name>X</name>
 7:  <version>1.0</version>
 8:  <dependencyManagement>
 9:    <dependencies>
 10:      <dependency>
 11:        <groupId>test</groupId>
 12:        <artifactId>a</artifactId>
 13:        <version>1.1</version>
 14:      </dependency>
 15:      <dependency>
 16:        <groupId>test</groupId>
 17:        <artifactId>b</artifactId>
 18:        <version>1.0</version>
 19:        <scope>compile</scope>
 20:      </dependency>
 21:    </dependencies>
 22:  </dependencyManagement>
 23: </project>

Y項目

 1: <project>
 2:  <modelVersion>4.0.0</modelVersion>
 3:  <groupId>maven</groupId>
 4:  <artifactId>Y</artifactId>
 5:  <packaging>pom</packaging>
 6:  <name>Y</name>
 7:  <version>1.0</version>
 8:  <dependencyManagement>
 9:    <dependencies>
 10:      <dependency>
 11:        <groupId>test</groupId>
 12:        <artifactId>a</artifactId>
 13:        <version>1.2</version>
 14:      </dependency>
 15:      <dependency>
 16:        <groupId>test</groupId>
 17:        <artifactId>c</artifactId>
 18:        <version>1.0</version>
 19:        <scope>compile</scope>
 20:      </dependency>
 21:    </dependencies>
 22:  </dependencyManagement>
 23: </project>

Z項目

 1: <project>
 2:   <modelVersion>4.0.0</modelVersion>
 3:   <groupId>maven</groupId>
 4:   <artifactId>Z</artifactId>
 5:   <packaging>pom</packaging>
 6:   <name>Z</name>
 7:   <version>1.0</version>
 8:   <dependencyManagement>
 9:     <dependencies>
 10:       <dependency>
 11:         <groupId>maven</groupId>
 12:         <artifactId>X</artifactId>
 13:         <version>1.0</version>
 14:         <type>pom</type>
 15:         <scope>import</scope>
 16:       </dependency>
 17:       <dependency>
 18:         <groupId>maven</groupId>
 19:         <artifactId>Y</artifactId>
 20:         <version>1.0</version>
 21:         <type>pom</type>
 22:         <scope>import</scope>
 23:       </dependency>
 24:     </dependencies>
 25:   </dependencyManagement>
 26: </project>
在這個例子中Z導入了X,Y,那麼兩個裏面都有a,可是因爲先導入X,全部a是1.1的版本。導入是遞歸的,若是X還導入了一個項目Q, 那麼Q也會被導入到Z。
須要注意的地方,不要導入當前POM的子POM,由於它沒法定位。
 
系統依賴
  經常被用來告知jdk和虛擬機中提供的依賴。
例一:
 1: <project>
 2:   ...
 3:   <dependencies>
 4:     <dependency>
 5:       <groupId>javax.sql</groupId>
 6:       <artifactId>jdbc-stdext</artifactId>
 7:       <version>2.0</version>
 8:       <scope>system</scope>
 9:       <systemPath>${java.home}/lib/rt.jar</systemPath>
 10:     </dependency>
 11:   </dependencies>
 12:   ...
 13: </project>

例二:

 1: <project>
 2:   ...
 3:   <dependencies>
 4:     <dependency>
 5:       <groupId>sun.jdk</groupId>
 6:       <artifactId>tools</artifactId>
 7:       <version>1.5.0</version>
 8:       <scope>system</scope>
 9:       <systemPath>${java.home}/../lib/tools.jar</systemPath>
 10:     </dependency>
 11:   </dependencies>
 12:   ...
 13: </project>

可選依賴

  可選依賴使用的狀況是對於某個依賴來講系統只有在某個特定的狀況下使用到它。例如數據庫驅動,有mysql的,oracle的。只有在咱們使用到mysql的時候纔會被使用。

使用方式

 1: <project>
 2:   ...
 3:   <dependencies>
 4:     <!-- declare the dependency to be set as optional -->
 5:     <dependency>
 6:       <groupId>sample.ProjectA</groupId>
 7:       <artifactId>Project-A</artifactId>
 8:       <version>1.0</version>
 9:       <scope>compile</scope>
 10:       <optional>true</optional> <!-- value will be true or false only -->
 11:     </dependency>
 12:   </dependencies>
 13: </project>

依賴排除

對於某些由於某些緣由被導入而你又不想引入的依賴進行排除。

 1: <project>
 2:   ...
 3:   <dependencies>
 4:     <dependency>
 5:       <groupId>sample.ProjectA</groupId>
 6:       <artifactId>Project-A</artifactId>
 7:       <version>1.0</version>
 8:       <scope>compile</scope>
 9:       <exclusions>
 10:         <exclusion>  <!-- declare the exclusion here -->
 11:           <groupId>sample.ProjectB</groupId>
 12:           <artifactId>Project-B</artifactId>
 13:         </exclusion>
 14:       </exclusions>
 15:     </dependency>
 16:   </dependencies>
 17: </project>
相關文章
相關標籤/搜索