dependencyManagement和dependencies之间的区别是什么? 我在Apache Maven网站上看过文档。 在dependencyManagement下定义的依赖项似乎可以在其子模块中使用,而无需指定版本。

例如:

父项目(Pro-par)在dependencyManagement下定义了一个依赖项:

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

然后在Pro-par的子函数中,我可以使用junit:

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

但是,我想知道是否有必要在父pom中定义junit ?为什么不在需要的模块中直接定义它呢?


当前回答

<dependencyManagement>的一个用例是解决库版本冲突。

例子:

项目A有库x:1.0.1 项目A有B库 B库有库x:1.0.0

有了这个设置,你会得到项目A同时x:1.0.1和x:1.0.0的冲突。 要解决这个问题,您可以将特定版本的依赖项放入<dependencyManagement>标签中

其他回答

有几个答案概述了maven的< dependencies >和<dependencyManagement>标记之间的区别。

但是,下面简要阐述了几点:

<dependencyManagement> allows to consolidate all dependencies (used at child pom level) used across different modules -- clarity, central dependency version management <dependencyManagement> allows to easily upgrade/downgrade dependencies based on need, in other scenario this needs to be exercised at every child pom level -- consistency dependencies provided in <dependencies> tag is always imported, while dependencies provided at <dependencyManagement> in parent pom will be imported only if child pom has respective entry in its <dependencies> tag.

<dependencyManagement>的一个用例是解决库版本冲突。

例子:

项目A有库x:1.0.1 项目A有B库 B库有库x:1.0.0

有了这个设置,你会得到项目A同时x:1.0.1和x:1.0.0的冲突。 要解决这个问题,您可以将特定版本的依赖项放入<dependencyManagement>标签中

在Eclipse中,dependencyManagement中还有一个特性。当使用依赖项而不使用它时,将在pom文件中注意到未找到的依赖项。如果使用dependencyManagement,则pom文件中不会发现未解决的依赖项,错误只出现在java文件中。(进口等…)

对不起,我迟到了。

让我尝试使用mvn dependency:tree命令来解释两者的区别

考虑下面的例子

父母POM -我的项目

<modules>
    <module>app</module>
    <module>data</module>
</modules>

<dependencies>
    <dependency>
        <groupId>com.google.guava</groupId>
        <artifactId>guava</artifactId>
        <version>19.0</version>
    </dependency>
</dependencies>

<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-lang3</artifactId>
            <version>3.9</version>
        </dependency>
    </dependencies>
</dependencyManagement>

子POM -数据模块

<dependencies>
    <dependency>
        <groupId>org.apache.commons</groupId>
        <artifactId>commons-lang3</artifactId>
    </dependency>
</dependencies>

子POM -应用程序模块(没有额外的依赖项,因此将依赖项留空)

 <dependencies>
</dependencies>

在运行mvn dependency:tree命令时,我们得到如下结果

Scanning for projects...
------------------------------------------------------------------------
Reactor Build Order:

MyProject
app
data

------------------------------------------------------------------------
Building MyProject 1.0-SNAPSHOT
------------------------------------------------------------------------

--- maven-dependency-plugin:2.8:tree (default-cli) @ MyProject ---
com.iamvickyav:MyProject:pom:1.0-SNAPSHOT
\- com.google.guava:guava:jar:19.0:compile

------------------------------------------------------------------------
Building app 1.0-SNAPSHOT
------------------------------------------------------------------------

--- maven-dependency-plugin:2.8:tree (default-cli) @ app ---
com.iamvickyav:app:jar:1.0-SNAPSHOT
\- com.google.guava:guava:jar:19.0:compile

------------------------------------------------------------------------
Building data 1.0-SNAPSHOT
------------------------------------------------------------------------

--- maven-dependency-plugin:2.8:tree (default-cli) @ data ---
com.iamvickyav:data:jar:1.0-SNAPSHOT
+- org.apache.commons:commons-lang3:jar:3.9:compile
\- com.google.guava:guava:jar:19.0:compile

谷歌guava在每个模块(包括父模块)中都被列为依赖项,而apache commons仅在数据模块中被列为依赖项(甚至不在父模块中)

两者之间的区别最好体现在Maven网站文档中提供的dependencyManagement元素的必要且充分的定义中:

dependencyManagement

从此继承的项目的默认依赖项信息。此部分中的依赖项不会立即解析。相反,当从这个POM派生的POM声明了一个由匹配的groupId和artifactId描述的依赖项时,如果这个节中的版本和其他值尚未指定,则将用于该依赖项。” [https://maven.apache.org/ref/3.6.1/maven-model/maven.html]

你可以在另一页阅读更多信息:

“. .匹配依赖引用到依赖管理节的最小信息集实际上是{groupId, artifactId, type, classifier}。在许多情况下,这些依赖关系将引用不带分类器的jar工件。这允许我们将标识集简写为{groupId, artifactId},因为类型字段的默认值是jar,默认分类器是null。[https://maven.apache.org/guides/introduction/introduction-to-dependency-mechanism.html]

Thus, all the sub-elements (scope, exclusions etc.,) of a dependency element--other than groupId, artifactId, type, classifier, not just version--are available for lockdown/default at the point (and thus inherited from there onward) you specify the dependency within a dependencyElement. If you’d specified a dependency with the type and classifier sub-elements (see the first-cited webpage to check all sub-elements) as not jar and not null respectively, you’d need {groupId, artifactId, classifier, type} to reference (resolve) that dependency at any point in an inheritance originating from the dependencyManagement element. Else, {groupId, artifactId} would suffice if you do not intend to override the defaults for classifier and type (jar and null respectively). So default is a good keyword in that definition; any sub-element(s) (other than groupId, artifactId, classifier and type, of course) explicitly assigned value(s) at the point you reference a dependency override the defaults in the dependencyManagement element.

因此,在dependencyManagement之外的任何依赖元素,无论是作为某个dependencyManagement元素的引用,还是作为独立的依赖元素,都将立即被解析(即安装到本地存储库并可用于类路径)。