在<依赖性管理>部分中声明依赖关系,即使依赖关系不是在所有地方都使用?

2022-09-02 11:23:57

我们使用的是 maven 2.1.0。我有多个模块是完全独立的,但仍然有许多共同的依赖项。像log4J,但有些模块不需要它。我想知道在本节的一个父文件中声明所有常见依赖项是否是一个好主意,或者是否有更好的方法来解决这个问题?<dependencyManagement>

有关 的后续问题。如果我在父项的部分声明Log4J,并且子项目不使用它,那么它是否会被包括在内?<dependencyManagement><dependencyManagement>


答案 1

如果您有父项目,则可以在父 pom 的依赖项管理部分中声明所有依赖项及其版本。这并不意味着所有项目都将使用所有这些依赖项,这意味着如果一个项目确实声明了依赖项,它将继承配置,因此它只需要声明依赖项的groupId和artifactId。您甚至可以在父级的依赖项管理中声明子项目,而无需引入周期。

请注意,您也可以通过在插件管理部分中声明插件来对插件执行类似的操作。这意味着任何声明插件的子级都将继承配置。

例如,如果您有 4 个项目:父项目核心项目、uiutils,则可以在父项目中声明所有外部依赖项和内部项目版本。然后,子项目将继承它们声明的任何依赖项的配置。如果所有模块都具有相同的版本,甚至可以在父级中将这些模块声明为属性。

示例父级如下所示:

<project>
  <modelVersion>4.0.0</modelVersion>
  <groupId>name.seller.rich</groupId>
  <artifactId>parent</artifactId>
  <version>1.0.0</version>
  <packaging>pom</packaging>
  <dependencyManagement>
    <dependencies>
      <dependency>
        <groupId>commons-io</groupId>
        <artifactId>commons-io</artifactId>
        <version>1.4</version>
      </dependency>
      <dependency>
        <groupId>name.seller.rich</groupId>
        <artifactId>ui</artifactId>
      <version>${project.version}</version>
      </dependency>
      <dependency>
        <groupId>name.seller.rich</groupId>
        <artifactId>core</artifactId>
        <version>${project.version}</version>
      </dependency>
      <dependency>
        <groupId>name.seller.rich</groupId>
        <artifactId>utils</artifactId>
        <version>${project.version}</version>
      </dependency>
    </dependencies>
  </dependencyManagement>
  <modules>
    <module>utils</module>
    <module>core</module>
    <module>ui</module>
  </modules>
</project>

实用程序、核心和 ui 项目继承所有相关版本。实用程序:

<project>
  <modelVersion>4.0.0</modelVersion>
  <groupId>name.seller.rich</groupId>
  <artifactId>utils</artifactId>
  <!--note version not declared as it is inherited-->
  <parent>
    <artifactId>parent</artifactId>
    <groupId>name.seller.rich</groupId>
    <version>1.0.0</version>
  </parent>
  <dependencies>
    <dependency>
      <groupId>commons-io</groupId>
      <artifactId>commons-io</artifactId>
    </dependency>
  </dependencies>
</project>

核心:

<project>
<modelVersion>4.0.0</modelVersion>
<groupId>name.seller.rich</groupId>
<artifactId>core</artifactId>
<parent>
  <artifactId>parent</artifactId>
  <groupId>name.seller.rich</groupId>
  <version>1.0.0</version>
</parent>
<dependencies>
  <dependency>
    <groupId>name.seller.rich</groupId>
    <artifactId>utils</artifactId>
  </dependency>
</dependencies>

用户界面:

<project>
  <modelVersion>4.0.0</modelVersion>
  <groupId>name.seller.rich</groupId>
  <artifactId>ui</artifactId>
  <parent>
    <artifactId>parent</artifactId>
    <groupId>name.seller.rich</groupId>
    <version>1.0.0</version>
  </parent>
  <dependencies>
    <dependency>
      <groupId>name.seller.rich</groupId>
      <artifactId>core</artifactId>
    </dependency>
  </dependencies>
</project>

答案 2

我写了一个最佳实践清单。以下是最重要的。

  • 始终使用 maven-enforcer-plugin
    • 实施依赖关系融合
      • 否则,您可能依赖于两个不同的jar,这两个jar都依赖于log4j。在编译时使用哪一个取决于一组规则,您不必记住这些规则。它们都可以 (!) 导出为传递依赖项。
    • 需要插件版本(适用于所有插件,甚至是内置插件)
      • 在插件中定义它们父 pom 中的管理以定义版本
      • 否则,新版本的maven-surefire-plugin可能会破坏您的构建
  • 使用依赖关系父 pom 中的管理,以便在所有模块中一致地使用版本
  • 定期运行 mvn 依赖项:分析
    • 您可能在编译时以传递方式获得直接依赖的依赖项。如果是这样,请务必将其添加到具有所需版本的pom中。这与执行器插件配合得很好。
    • 您可能正在声明不使用的额外依赖项。这不能100%正常工作,特别是对于设计为具有可选部分的库(即slf4j-api被正确检测到,但slf4j-log4j12失败)。

推荐