如果它们来自父模块的其他子模块,我是否应该依赖Maven中的可传递依赖项?

如果它们来自父模块的其他子模块,我是否应该依赖Maven中的可传递依赖项?,maven,dependencies,pom.xml,parent-pom,transitive-dependency,Maven,Dependencies,Pom.xml,Parent Pom,Transitive Dependency,假设我们正在处理抵押子模块,并且我们直接使用模块代码中的谷歌番石榴类,但是番石榴的依赖关系在同一父模块下的其他子模块中定义,我们只能通过对“投资”模块的传递依赖来访问番石榴类: 当使用@Component时,仍然应该Investment显式声明Spring,如果使用Guava的LoadedCache?当模块使用第三方库时,该模块也应该显式依赖其pom.xml中的库。想象一下,如果另一个项目应该使用“抵押”模块,并且不依赖于Guava,它将失败,例如,当单元测试遇到涉及Guava的代码路径时。一个

假设我们正在处理抵押子模块,并且我们直接使用模块代码中的
谷歌番石榴
类,但是
番石榴
的依赖关系在同一父模块下的其他子模块中定义,我们只能通过对“投资”模块的传递依赖来访问番石榴类:


当使用
@Component
时,仍然应该
Investment
显式声明Spring,如果使用Guava的
LoadedCache

当模块使用第三方库时,该模块也应该显式依赖其pom.xml中的库。想象一下,如果另一个项目应该使用“抵押”模块,并且不依赖于Guava,它将失败,例如,当单元测试遇到涉及Guava的代码路径时。一个显式的依赖关系还可以让您避免重构“投资”模块,使其不再使用Guava。您的“投资”模块应该对其依赖项中的此类更改不敏感

明确列出直接依赖项总是正确的。说到版本,最好将其保留在父pom的
dependencyManagement
部分,以便所有子项目都继承该(相同)版本

  • 是的,声明dep。它不是复制品!!!编译依赖项是可传递的并不是maven开发人员想要的,而是java语言强制的。因为类继承之类的特性强制了这种行为。你已经提到的“专业”是一个重要的事实。 看

  • ,始终使用DependencyManager在反应堆父级中声明所需的第三方库版本。在运行时发现来自不同lib版本的错误是一件痛苦的事情。避免在大型反应堆的子模块中声明第三方LIB的版本,始终在父模块中使用depMngs

  • ,我将仅对运行时提供的依赖项使用“提供的”,在您的示例tomcat/jboss/wildfly/中。。对于ServletAPI/CDIAPI/之类的东西。但不适用于第三方库。 尽可能晚地声明“提供的”范围(即部署模块war/ear),而不是在业务模块中。这使得编写测试更容易。 例如:

    • 投资(取决于番石榴范围:=提供的
    • 抵押贷款(取决于投资,但不需要番石榴本身)
  • -->抵押贷款类路径不包含番石榴。 如果您为抵押贷款编写单元测试,其中涉及投资的类将不起作用->您需要使用scope=test/runtime至少声明guava来运行这些测试

    我们在模块代码中直接使用GoogleGuava类,但是 番石榴的依赖性在同一目录下的其他子模块中定义 parent和我们只能通过传递函数访问Guava类 依赖于“投资”模块[…]我们是否仍应该在mortgage pom.xml中添加Guava

    ,您应该在模块中声明Google Guava依赖项,而不是期望它作为可传递依赖项可用。即使它与当前版本一起工作,在直接依赖关系的更高版本中也可能不再如此

    如果您的代码依赖于一个模块,那么您的代码应该只直接依赖于该模块的类,而不是该模块的可传递依赖项。正如你提到的,不能保证投资模块将来会继续依赖番石榴。您需要在父级的pom.xml或模块本身中指定此依赖项,以确保它在不依赖可传递依赖项的情况下可用。这不是重复,否则你怎么能告诉Maven你的模块依赖于番石榴呢

    我不认为在任何情况下,在您需要采取其他措施的情况下,会尊重最低限度的最佳实践

    如果是,那么我们应该指定什么?(在父pom中无+

    ,在父模块中使用
    ,在没有版本的子模块中使用
    是最好的:您将确保所有模块使用相同版本的依赖项。由于您的模块作为一个整体是一个应用程序,它可能会更好,因为它将避免各种问题,例如在类路径上存在同一依赖项的不同版本,从而造成严重破坏

    即使出于某种原因,使用同一父模块的某个模块需要不同版本的依赖项,仍然可以使用
    覆盖此特定模块的版本

    如果是,那么我们是否应该在某些模块中使用范围

    可能不,拥有
    编译
    范围的依赖关系是大多数打包方法的最佳选择


    但是在某些情况下,您可能需要或更愿意这样做,例如,如果所述模块需要使用运行时环境特定的版本,或者如果您的部署或打包模型是按要求设计的。考虑到您所暴露的情况,这两种情况都是可能的,尽管大多数情况下这是不必要的

    我会复制并让家长中的dependencyManagement负责版本。可能会复制,但请记住,
    抵押贷款
    模块明确要求
    投资
    模块,因此当有人依赖
    抵押贷款
    “ony”,无论如何,它都会利用guava alsoExplicit吸引
    投资
    ,对于模块中使用的所有代码来说,依赖关系仍然是一条必经之路。我用另一个例子更新了我的答案。
    banking-system (parent pom.xml)
    |
    |-- investment (pom.xml defines <dependency>guava</dependency>)
    |
    |-- mortgage (pom.xml defiens <dependency>investment</dependency>)
    
    banking-app
        banking-core (dep.on: guava, commons, spring)
        investment (dep.on: banking-core)
        mortgage (dep.on: banking-core)