当前位置: 首页 > 知识库问答 >
问题:

应用于分组依赖项的作用域的Maven效果

钮才哲
2023-03-14

我有一个POM,根据Maven的最佳实践,它应该对组件/系统的依赖项进行分组,以声明使用该组件/系统所需的任何依赖项。(只有分组本身是最佳实践;))

正常情况下,此pom只将组件(在本例中为systemA)服务(接口)模块声明为compile作用域依赖项,并将其相应的实现模块声明为runtime作用域依赖项,如下所示:

<dependencies>
    <dependency>
        <groupId>ch.jeeguy.systemA</groupId>
        <artifactId>systemA-service</artifactId>
        <scope>compile</scope>
    </dependency>

    <dependency>
        <groupId>ch.jeeguy.systemA</groupId>
        <artifactId>systemA-implementations</artifactId>
        <scope>runtime</scope>
    </dependency>
</dependencies>

(当然,服务模块的POM和实现模块的POM将声明对systemA模块的进一步依赖关系,例如systemA的DTO模块需要作用域、编译等。)

因此,如果我现在计划构建一个新的systemB,它需要与systemA交互或重用systemA的某些部分,我不希望systemB依赖于systemA的internas(例如它的DTO-module),而只希望依赖于上述POM。这就是我在SystemB中添加上述POM作为dependencie的方式:

        <dependency>
            <groupId>ch.jeeguy.systemA</groupId>
            <artifactId>systemA</artifactId>
            <type>pom</type>
            <version>${systemA.version}</version>
        </dependency>

正如faar所理解的那样,我的componentB现在将Systema的服务模块作为compilescope depencency和实现模块作为runtimescope depencency-它们各自定义了自己的依赖项,这些依赖项将成为systemB的传递依赖项,其行为类似于这里定义的(作用域矩阵):http://maven.apache.org/guides/introduction/introduction-to-dependency-mechanism.html#dependency_scope。

我的问题是:如果我应用范围...重写默认的commpile...对SystemB的POM中systemA的POM类型依赖项设置test,如下所示:

        <dependency>
            <groupId>ch.jeeguy.systemA</groupId>
            <artifactId>systemA</artifactId>
            <type>pom</type>
            <scope>test</scope>
            <version>${systemA.version}</version>
        </dependency>

我现在到底在什么上应用test作用域?是下面的选择吗?

>

  • 我将作用域应用于整个POM-dependencie-invession i applyedtest除非给出上下文test,否则根本不会考虑systemA的POM中定义的整个信息(如果编译systemB跳过测试,则不参考组中定义的任何信息-POM)。一旦给出上下文test,将导致systemB获得compileruntime依赖项,这些依赖项在此上下文中不会产生任何影响。.->“作用域应用于POM本身”

    我覆盖了systemA的POM中定义的任何依赖项的作用域-在本例中,这将导致systemB仅依赖于systemA的模块进行测试。systemA的两个依赖项的编译/运行时范围位于systemB的上下文中,都设置为test。(例如,“我不在乎您希望我使用带有scopecompile的服务模块,我希望它具有scopetest!”)->“作用域应用于根据POM中的依赖项,从而影响传递依赖项的行为”

    你能帮我摆脱困惑吗?我努力想弄清楚这件事?

    我尝试了什么

    即便如此,我对Maven还是新手,我也不怕阅读整个文档以及我订购的一本关于Maven3的书。我投资了一个项目。80-100小时进入我的专业“技能”所以Faar。我还或多或少地“完全”理解了至少作用域import在涉及dependencymanagement信息时的行为,如这里所描述的:作用域“import”和“pom”类型依赖性之间的区别,但我无法找到我的问题的(官方)来源。在我看来,有两种可能性:我只是浏览了文档中的相应部分,或者(不幸的是,这更有可能)我已经对Maven的概念有了很大的误解。尤其是在后面的例子中,我希望得到澄清:)顺便说一句。我目前正试图通过应用不同的作用域和分析构建输出来恢复行为...但我正在处理15个系统和数百个模块...


  • 共有1个答案

    祁绪
    2023-03-14

    关于这个问题,我可以咨询我们公司的首席架构师--在这里提供来源答案:

    1.)让我们将只对两个依赖项(systemA-service、systemA-Impl)进行分组的systemA的pom称为“端口pom”。

    快速回答:systemB中定义的作用域适用于(systemA的)端口pom本身,因此使该pom中的任何分组依赖项成为可传递的,并根据http://maven.apache.org/guides/introduction/introduction-to-dependency-mechanism.html#dependency_scope for systemB下的矩阵表进行操作。

    回到我的问题--被质疑的范围(绿色标记,下面的大箭头)如下所示:

    将依赖项分组到Systema的Service/Impl模块的端口pom(这些模块本身将定义进一步的依赖项,如eclipselink等,并且可以分组到组件父级下)导致一个工件ch.jeeguy.systema:systema: ion>beeing填充到存储库(绿框)。

    如果systemB(黄色框)现在向pom端口添加了一个依赖项,它就会向上面的(绿色框)人工制品添加一个依赖项,从而使人工制品本身成为systemB的直接依赖项,而从systemB的角度来看,任何进一步的依赖项(分组的那些--橙色框)都成为可传递的依赖项。

    既然我们现在知道了这些是传递依赖关系,我们就可以回答beeing所应用的作用域的影响:它的行为就像传递依赖关系一样,根据Mavens的文档(请参见快速回答下的链接)。

    关于我询问的范围(箭头指向的地方)-这意味着:

    >

  • 如果没有应用作用域-默认作用域compile应用-在上述场景中,systemA-service将在作用域compile中临时可用,而systemA-Impl将在作用域runtime中临时可用。

    如果应用了另一个作用域,传递依赖关系的行为将根据作用域矩阵(例如,scopetestprovide的传递依赖关系将被省略)。

    示例1:如果应用范围provided,则范围compileruntime的传递依赖项也将在范围provide中可用(例如,systemA-service在范围compile中不可用,而只能在范围provide中可用)。

    示例2:如果应用了scoperuntime,那么scopecompileruntime的传递依赖项也可以在scoperuntime中使用。

    考虑到我们有一个新的策略,只创建对系统端口pom的新依赖项,我们也必须防止在策略中的这一点上使用范围(“使用强制”maven方法的漏洞是非常有问题的,但我们的主要目标是使maven结构尽可能接近我们的组件设计。

    资料来源

    >

  • 传递依赖关系的行为:http://maven.apache.org/guides/introvidion/introvide-to-dependency-mechanism.html

    作用域import->http://maven.apache.org/guides/introduction/introduction-to-dependency-mechanism.html#importing_dependencies

    旁注“最佳实践”:在我的问题的评论部分,您可以看到我们试图在上下文中应用最佳实践的原因,我也可以确认,从“Maven只是配置”的角度来看,这似乎是合理的。然而,考虑到applicationB只需要systemA的DAO-模块--使用这样的端口POM将导致applicationB获得各种依赖项人工制品(例如systemA-service、systemA-Impl和它们的一些传递依赖项),它永远不会真正用于遵循companys maven指南的唯一目的。我看到一些耳朵从50mbs爆炸到150mbs以上,仅仅是因为作用域compile中的传递依赖关系。因此,在这个场景中要注意这个方面,并注意您不希望排除systemB中的传递依赖关系,因为您不希望在systemB的pom中有任何其他SystemA-Module,除非它是允许重构systemA的任何模块而不对systemB进行任何更改的端口pom模块[除非端口pom本身受到影响])。

  •  类似资料:
    • 我创建了一个基于Maven的spring引导项目来探索如何使其在Websphere Application Server上运行。这是我需要排除spring-boot-starter-web的嵌入式Tomcat的方法。 我试过以下几件事: 为spring-boot-starter-tomcat添加了一个新的依赖项,其作用域为:provided(请参见在部署到JBOSS[spring-boot])时从

    • 我有一个简单的java应用程序-maven项目在我的Netbean IDE。 在我创建Maven Web Application并添加第一个项目作为依赖项之后,Netbean显示一切都很好,我也可以使用所有方法。 但在运行时,我会 在不创建多模块JavaEE应用程序的情况下,是否有可能使web项目依赖于简单的java应用程序?

    • 我对匕首2还不太熟悉。我正试图在我的Android项目中实现它。我有一个需要。我用匕首把它注射到这个服务中。 、和具有标记为的方法当我构建项目时,我收到以下错误: locationServiceComponent依赖于多个作用域组件:@Singleton NetComponent@Singleton RepositoryComponent 我知道我的不能依赖于两个作用域组件,但我的服务中需要这两个

    • 我正在使用m2e插件在eclipse中开发一个java maven项目。我更新了我的系统和我的jvm从Icedtea-bin-6.1.11.4更新到Icedtea-bin-6.1.11.5。Eclipse现在在我的pom文件中输出下面的错误,我无法运行我的项目。我是maven和eclipse的新手,在搜索了一天之后,我仍然没有找到解决方案。 我个人认为这是eclipse的某种问题(配置错误?),因

    • 如果您注意到了,以下代码出现在所有三个函数中: 功能组合 在函数式编程中,我们可以将函数融合在一起,这样它们就可以成为一个函数。 并将其重构为: 我关于函数组合与部分应用程序耦合的想法是否准确?