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 ?为什么不在需要的模块中直接定义它呢?


当前回答

有几个答案概述了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.

其他回答

用我自己的话来说,你的父项目帮助你提供了两种依赖:

implicit dependencies : all the dependencies defined in the <dependencies> section in your parent-project are inherited by all the child-projects explicit dependencies : allows you to select, the dependencies to apply in your child-projects. Thus, you use the <dependencyManagement> section, to declare all the dependencies you are going to use in your different child-projects. The most important thing is that, in this section, you define a <version> so that you don't have to declare it again in your child-project.

在我看来,<dependencyManagement>(如果我错了请纠正我)只是通过帮助您集中依赖项的版本而有用。它就像一种辅助功能。 作为最佳实践,您的<dependencyManagement>必须在父项目中,其他项目将继承它。一个典型的例子是通过声明Spring父项目来创建Spring项目。

如果依赖项是在顶级pom的dependencyManagement元素中定义的,子项目就不必显式地列出依赖项的版本。如果子项目确实定义了一个版本,它将覆盖顶层中列出的版本 POM的依赖管理部分。也就是说,dependencyManagement版本仅为 当子进程没有直接声明版本时使用。

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

有几个答案概述了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.

The documentation on the Maven site is horrible. What dependencyManagement does is simply move your dependency definitions (version, exclusions, etc) up to the parent pom, then in the child poms you just have to put the groupId and artifactId. That's it (except for parent pom chaining and the like, but that's not really complicated either - dependencyManagement wins out over dependencies at the parent level - but if have a question about that or imports, the Maven documentation is a little better).

After reading all of the 'a', 'b', 'c' garbage on the Maven site and getting confused, I re-wrote their example. So if you had 2 projects (proj1 and proj2) which share a common dependency (betaShared) you could move that dependency up to the parent pom. While you are at it, you can also move up any other dependencies (alpha and charlie) but only if it makes sense for your project. So for the situation outlined in the prior sentences, here is the solution with dependencyManagement in the parent pom:

<!-- ParentProj pom -->
<project>
  <dependencyManagement>
    <dependencies>
      <dependency> <!-- not much benefit defining alpha here, as we only use in 1 child, so optional -->
        <groupId>alpha</groupId>
        <artifactId>alpha</artifactId>
        <version>1.0</version>
        <exclusions>
          <exclusion>
            <groupId>zebra</groupId>
            <artifactId>zebra</artifactId>
          </exclusion>
        </exclusions>
      </dependency>
      <dependency>
        <groupId>charlie</groupId> <!-- not much benefit defining charlie here, so optional -->
        <artifactId>charlie</artifactId>
        <version>1.0</version>
        <type>war</type>
        <scope>runtime</scope>
      </dependency>
      <dependency> <!-- defining betaShared here makes a lot of sense -->
        <groupId>betaShared</groupId>
        <artifactId>betaShared</artifactId>
        <version>1.0</version>
        <type>bar</type>
        <scope>runtime</scope>
      </dependency>
    </dependencies>
  </dependencyManagement>
</project>

<!-- Child Proj1 pom -->
<project>
  <dependencies>
    <dependency>
      <groupId>alpha</groupId>
      <artifactId>alpha</artifactId>  <!-- jar type IS DEFAULT, so no need to specify in child projects -->
    </dependency>
    <dependency>
      <groupId>betaShared</groupId>
      <artifactId>betaShared</artifactId>
      <type>bar</type> <!-- This is not a jar dependency, so we must specify type. -->
    </dependency>
  </dependencies>
</project>

<!-- Child Proj2 -->
<project>
  <dependencies>
    <dependency>
      <groupId>charlie</groupId>
      <artifactId>charlie</artifactId>
      <type>war</type> <!-- This is not a jar dependency, so we must specify type. -->
    </dependency>
    <dependency>
      <groupId>betaShared</groupId> 
      <artifactId>betaShared</artifactId> 
      <type>bar</type> <!-- This is not a jar dependency, so we must specify type. -->
    </dependency>
  </dependencies>
</project>