Различия между dependencyManagement и зависимостями в Maven


в чем разница между 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>

однако, интересно, если это необходимо определить junit в Родительском pom? Почему бы не определить его в нужный модуль?

9 526

9 ответов:

Управление Зависимостями позволяет консолидировать и централизовать управление версиями зависимостей без добавления зависимостей, которые наследуются всеми детьми. Это особенно полезно, когда у вас есть набор проектов (т. е. более одного), который наследует общий родитель.

еще один чрезвычайно важный случай использования dependencyManagement - это управление версиями артефактов, используемых в транзитивных зависимостях. Это трудно объяснить без примера. К счастью, это проиллюстрировано в документации.

Я модно опаздываю на этот вопрос, но я думаю, что это стоит более четкого ответа, чем принятый (что правильно, но не подчеркивает фактическую важную часть, которую вам нужно вывести самостоятельно).

в Родительском POM, основное различие между <dependencies> и <dependencyManagement> это:

артефакты, указанные в <dependencies> раздел всегда будет включен как зависимость ребенка модуль(ы).

артефакты, указанные в <dependencyManagement> раздел, будет включен только в дочерний модуль, если они также были указаны в <dependencies> раздел самого дочернего модуля. Почему это хорошо, спросите вы? потому что вы указываете версию и/или область в родительском элементе, и вы можете оставить их при указании зависимостей в дочернем POM. Это может помочь вам использовать унифицированные версии для зависимостей для дочерних модулей, не указывая версию в каждый дочерний модуль.

все так, как ты сказал; dependencyManagementиспользуется для извлечения всей информации о зависимостях в общий файл POM, упрощая ссылки в дочернем файле POM.

это становится полезным, когда у вас есть несколько атрибутов, которые вы не хотите сохранять их в нескольких детских проектов.

наконец, dependencyManagement можно использовать для определения стандартной версии артефакта для использования в нескольких проектах.

на документация на сайте Maven-это ужасно. То, что dependencyManagement делает, просто перемещает ваши определения зависимостей (версия, исключения и т. д.) до родительского pom, а затем в дочерних POM вам просто нужно поместить groupId и artifactId. Вот и все (за исключением Родительской Цепочки pom и тому подобного, но это тоже не очень сложно - dependencyManagement побеждает над зависимостями на родительском уровне - но если у вас есть вопрос об этом или импорте, Maven документация немного лучше).

прочитав весь мусор "a", "b", " c " на сайте Maven и запутавшись, я переписал их пример. Поэтому, если у вас есть 2 проекта (proj1 и proj2), которые имеют общую зависимость (betaShared), вы можете переместить эту зависимость до родительского pom. В то время как вы находитесь на нем, вы также можете перемещать любые другие зависимости (альфа и Чарли), но только если это имеет смысл для вашего проекта. Итак, для ситуации, изложенной в предыдущих предложениях, вот решение с dependencyManagement в Родительском 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>

есть еще одна вещь, которая не достаточно освещены, на мой взгляд, и это нежелательного наследства.

вот поэтапный пример:

я заявляю в моем parent pom:

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

бум! У меня это в моей Child A,Child B и Child C модули:

  • Имплицитность наследуется дочерними poms
  • единственное место для управления
  • нет необходимости переоформлять что-либо в ребенка помпоны
  • я все еще могу redelcare и переопределить на version 18.0 на Child B Если я хочу.

но что, если мне не понадобится гуава в Child C, и ни в будущем Child D и Child E модули?

они все равно унаследуют его, и это нежелательно! Это так же, как запах объектного кода Java God, где вы наследуете некоторые полезные биты из класса, а также тонну нежелательных вещей.

вот тут <dependencyManagement> вступать в игру. Когда вы добавляете это в свой родительский pom, все ваши дочерние модули перестань это видеть. И таким образом ты заставили чтобы войти в каждый отдельный модуль, который нуждается в нем, и объявить его снова (Child A и Child B, без хотя версия).

и, очевидно, вы не делаете это для Child C, и, таким образом, ваш модуль остается худой.

Если зависимость была определена в элементе dependencyManagement POM верхнего уровня, Дочерний проект не должен был явно перечислять версию зависимости. если Дочерний проект определил версию, он переопределит версию, указанную на верхнем уровне Раздел ПЦМ dependencyManagement. То есть, версия dependencyManagement только используется, когда дочерний элемент не объявляет версию напрямую.

есть несколько ответов, описывающих различия между <depedencies> и <dependencyManagement> теги с maven.

однако, несколько пунктов, разработанных ниже в сжатом виде:

  1. <dependencyManagement> позволяет консолидировать все зависимости (используемые на дочернем уровне pom), используемые в разных модулях -- ясность,централизованное управление версиями зависимостей
  2. <dependencyManagement> позволяет легко обновлять / понижать зависимости на основе необходимости, в других сценарий это должно быть осуществлено на каждом уровне POM ребенка -- последовательность
  3. зависимости, предоставляемые в <dependencies> тег всегда импортируется, а зависимости предоставляются в <dependencyManagement> в родительский pom будет импортирован только если дочерний pom имеет соответствующую запись в своем <dependencies> тег.

в Родительском POM, основное различие между <dependencies> и <dependencyManagement> это:

артефакты, указанные в <dependencies> раздел всегда будет включен в качестве зависимости от дочернего модуля(ов).

артефакты, указанные в разделе, будут включены в дочерний модуль только в том случае, если они также были указаны в разделе самого дочернего модуля. Почему это хорошо, спросите вы? потому что вы указываете версию и / или область в родительском элементе, и вы можете оставить их при указании зависимостей в дочернем пом. Это может помочь вам использовать унифицированные версии для зависимостей для дочерних модулей, не указывая версию в каждом дочернем модуле.

в Eclipse есть еще одна функция в dependencyManagement. Когда dependencies используется без него, не найденные зависимости замечены в файле pom. Если dependencyManagement используется, неразрешенные зависимости остаются незамеченными в файле pom и ошибки появляются только в файлах java. (импорт и тому подобное...)