1. 程式人生 > >Maven的排除依賴、歸類依賴、優化依賴

Maven的排除依賴、歸類依賴、優化依賴

排除依賴

傳遞性依賴會給專案隱式地引入很多依賴,著極大簡化了專案依賴的管理,但是有些時候這種特性也會帶來問題。例如,當前專案有一個第三方依賴,而這個第三方依賴由於某些原因依賴了另一個類庫的SNAPSHOT版本,那麼這個SNAPSHOT就會成為當前專案的傳遞性依賴,而SNAPSHOT的不穩定性會直接影響到當前的專案。這時就需要排除掉該SNAPSHOT,並且在當前專案中宣告該類庫的某個正式釋出的版本。還有一些情況,你可能也想要替換掉某個傳遞性依賴,比如Sun JTA API,Hibernate依賴與這個JAR,但是由於版權的因素,該類庫不在中央倉庫中,而Apache Geronimo專案有一個對應的實現。這時你就可以排除Sun JAT API,而宣告Geronimo的JTA API實現。

<project>
  <modelVersion>4.0.0</modelVersion>

  <groupId>com.cc.maven</groupId>
  <artifactId>project-a</artifactId>
  <version>1.0.0</version>
  <packaging>jar</packaging>


  <dependencies>
    <dependency>
      <groupId>
com.cc.maven</groupId> <artifactId>project-b</artifactId> <version>1.0.0</version> <exclusions> <exclusion> <groupId>com.cc.maven</groupId> <artifactId>project-c</artifactId> </exclusion
>
</exclusions> </dependency> <dependency> <groupId>com.cc.maven</groupId> <artifactId>project-b</artifactId> <version>1.1.0</version> </dependency> </dependencies> </project>

上述程式碼中,專案A依賴於專案B,但是由於一些原因,不想引入傳遞性依賴C,而是自己顯式宣告對專案C 1.1.0版本的依賴。程式碼中使用exclusions元素宣告排除依賴,exclusions可以包含一個或者多個exclusion子元素,因此可以排除一個或者多個傳遞性依賴。需要注意的是,宣告exclusion的時候只需要groupId和artifactId,而不需要version元素,這是因為只需要groupId和artifactId就能唯一定位依賴圖中的某個依賴。換句話說,maven解析後的依賴中,不可能出現groupId和artifactId專案,但是version不同的兩個依賴。該例的依賴解析邏輯如下所示:
這裡寫圖片描述

歸類依賴

關於Spring Framework的依賴有很多,他們來自同一個專案的不同模組。因此所有這些依賴的版本都是相同的,可以知道,如果將來想要升級Spring Framework的話,這些依賴版本也會一起升級。這一情況在java中也似曾相識,考慮程式碼如下:

public double c(double r){
    return 2 * 3.14 * r;
}

public double s(double r){
    return 3.14 * r * r;
}

這兩個簡單的方程式計算圓的周長和麵積,有經驗的程式設計師一眼就能看出問題,使用字面量3.14顯然不合適,應該定義一個常量並在方法中使用,如下:

public final double PI = 3.14;

public double c(double r){
    return 2 * PI * r;
}

public double s(double r){
    return PI * r * r;
}

使用常量不僅可以使程式碼變得更加簡潔,更重要的是可以避免重複,只需要更改一處,降低了錯誤的概率。
使用maven屬性歸類依賴:

<project>
  <modelVersion>4.0.0</modelVersion>

  <groupId>com.juven.mvnbook.account</groupId>
  <artifactId>account-email</artifactId>
  <version>1.0.0-SNAPSHOT</version>
  <name>Account Email</name>


  <properties>
     <springframework.version>2.5.6</springframework.version>
  </properties>

  <dependencies>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-core</artifactId>
      <version>${springframework.version}</version>
    </dependency>

     <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-context</artifactId>
      <version>${springframework.version}</version>
    </dependency>

     <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-context-support</artifactId>
      <version>${springframework.version}</version>
    </dependency>
  </dependencies>
</project>

這裡簡單使用到了Maven的屬性,首先使用properties元素定義了Maven的屬性,該例子中定義了一個springframework.version子元素,其值為2.5.6,有了這個屬性之後,Maven執行的時候,會將POM中所有${springframework.version}替換成2.5.6,也就是說,可以使用${}的方式來引用Maven的屬性,然後將所有Spring Framework依賴的版本值用這一屬性引用。這個和在java中常量PI替換3.14是同樣的道理,只是語法不同而已。

優化依賴

在軟體開發的過程中,程式設計師會通過重構等方式不斷地優化自己的程式碼,使其變得更簡潔、更靈活。同理,程式設計師也應該能夠對maven專案的依賴瞭然於胸,並對其優化,如去除多餘的依賴,顯式宣告某些必要的依賴。
maven會自動解析所有專案的直接依賴和傳遞性依賴,並且根據規則正確判斷每個依賴的範圍。對於一些依賴衝突,也能進行調解,以確保任何一個構件只能唯一的版本在依賴中存在。在這些工作之後,最後得到的那些依賴被稱為已解析依賴。
可以通過執行如下命令檢視當前專案的已解析依賴:mvn dependency:list
這裡寫圖片描述
將直接在當前POM宣告的依賴定義為頂層依賴,而這些頂層依賴的依賴則定義為第二層依賴,以此類推,有第三、第四層依賴。當這些依賴經過Maven解析之後,就會構成一個依賴樹,通過這顆依賴樹,就能夠很清楚地看到某個依賴是通過哪條路徑引入的。可以執行如下命令檢視當前專案的依賴樹:mvn dependency:tree
這裡寫圖片描述

使用mvn dependency:listmvn dependency:tree可以幫助我們詳細瞭解專案中所有的依賴的具體詳細,在此基礎上,還有mvn dependency:analyze工具可以幫助分析當前專案的依賴
這裡寫圖片描述