2013-03-05 294 views
39

我通常在parent-project/pom.xml中放置一個<dependencyManagement>部分。這<dependencyManagement>部分包含聲明和版本爲我的孩子們的模塊,比如這一切都依賴(即沒有0​​元素):依賴管理和範圍

<dependencyManagement> 
    <dependencies> 
    <dependency> 
     <groupId>junit</groupId> 
     <artifactId>junit</artifactId> 
     <version>4.10</version> 
    </dependency> 
    </dependencies> 
</dependencyManagement> 

在所有兒童模塊(即MODULEX/pom.xml的),我有:

<dependencies> 
    <dependency> 
    <groupId>junit</groupId> 
    <artifactId>junit</artifactId> 
    <scope>test</scope> 
    </dependency> 
    </dependencies> 

顯然,在這個例子中,我重複多次使用<scope>test</scope>來獲得相同的依賴關係(每個子模塊需要junit一次)。

我的問題是:有關<scope>聲明的最佳做法是什麼?把它放在<dependencyManagement>中是否更好?或者更好地把它放在孩子模塊的<dependencies>部分(就像在這篇文章中那樣)?爲什麼?這個問題有什麼明確的答案嗎?

回答

34

晚會有點晚,但我會補充我的兩分錢。我最近遇到了一個非常難以調試的問題。我有一個用於管理多個項目之間依賴項的父類。我設置了它們之間的所有相關性,包括groupId,artifactId,版本和最常見的範圍。我的想法是,如果符合最常見的範圍,我不必在每個項目的實際依賴項部分中包含範圍。當一些依賴顯示爲傳遞依賴時,問題就出現了。例如,如果

  • 甲在編譯範圍依賴於B
  • 乙在編譯範圍取決於第C
  • C被設置爲在dependencyManagement提供的父的

然後在C A的傳遞依賴被確定提供。我不確定這是否合理,但它確實令人困惑。

無論如何,保存你的麻煩,並讓你的依賴管理的範圍。

+3

它是有道理的,但沒有很好的記錄,請參閱http://maven.40175 .n5.nabble.com/DependencyManagement-to-force-scope-td112273.html,我在下面編輯我的答案 – Gab 2015-08-09 07:53:38

2

對於任何範圍,向依賴項管理添加單個依賴項沒有任何好處。你所擁有的就是重複。如果你想擁有的版本配置,添加屬性,並在你的依賴使用它:

<properties> 
     <junit.version>4.10</junit.version> 
    ... 
    <dependency> 
     <groupId>junit</groupId> 
     <artifactId>junit</artifactId> 
     <version>${junit.version}</version> 
    </dependency> 
</dependencies> 

然而,也有情況下依賴管理眼前一亮 - 當你以協調版本的使用boms較大的文物收藏,就像使用Java EE實現的某個版本:

<dependencyManagement> 
    <dependencies> 
     <dependency> 
      <groupId>org.jboss.bom</groupId> 
      <artifactId>jboss-javaee-6.0-with-tools</artifactId> 
      <version>${javaee6.with.tools.version}</version> 
      <type>pom</type> 
      <scope>import</scope> 
     </dependency> 
.... 
+3

dependencyManagement(即使只有一個依賴項)是定義工件版本的唯一位置。在我看來,這一事實足以使用它。使用屬性非常有用,因爲您有多個始終具有相同versionId的工件(例如spring模塊) – ben75 2013-03-05 11:16:29

+0

使用dependencyManagement的另一個原因是爲集中排除依賴關係的不需要的傳遞依賴關係。 – 2016-04-27 13:46:31

+0

使用屬性版本的另一個原因是,您可以使用'mvn版本:display-property-updates'快速檢查依賴版本更新 - 只要您注意在artifactId.version中命名您的版本屬性'pattern – 2016-12-14 17:45:22

13

dependencyManagement只是這裏定義依賴版本的所有項目的子模塊,在本節的唯一相關的範圍import的物料清單。

範圍必須在dependencies部分定義。

(對於給定的依賴它確定使用上下文,它允許以僅包括當需要用於執行的依賴關係。例如耳不會與Java-EE的依賴關係(範圍provided),因爲它會被包裝發現它們在目標服務器上。)

[編輯]

第一條語句有一個例外,範圍provideddependencyManagement節將覆蓋定義範圍,dependencies部分。請參閱DependencyManagement to force scope

+2

「本節中唯一相關的作用域是導入」是否意味着如果我將範圍'test'放在'dependendcyManagement'中:它沒有效果? – ben75 2013-03-05 10:37:24

+1

不,它有效果 – Gab 2013-03-05 10:47:38

+4

事實上,我似乎並不完全正確。 http://maven.40175.n5.nabble.com/DependencyManagement-to-force-scope-td112273.html'dependencyManagement'範圍有興趣 – Gab 2013-03-05 10:51:55

2

與其他答案一樣,最好的做法是將範圍從dependencyManagement中排除,並在定義依賴關係時明確指定它。很少見的情況是,您希望在不同範圍內使用不同版本的相同依賴項,例如,在編譯應用程序時使用一個版本,而在運行時使用不同版本 - 唯一可以考慮的情況是要明確運行您的應用程序在用戶使用該版本而不是您指定的版本的情況下,針對不同版本的庫進行測試。

如果您在dependencyManagement中定義了作用域,它將該版本的使用限制爲僅定義的作用域 - 因此任何其他作用域都將選擇隨機版本的依賴關係。我昨天遇到了這個問題,當時我們在測試作用域的dependencyManagement中定義了junit 4.12,但我們常見的測試框架模塊使用了junit和編譯範圍,所以它改爲使用4.8.2版本。