从第一份工作干到现在,越干遗忘的东西越多,本文用于Maven构建项目的温习!

Maven依赖传递冲突三法则

路优优先

引用层级越短越有优先

【示例】project01 Maven的坐标引入log4j:1.2.17、project02。project01引入log4j:1.2.17对于project01自身的log4j来说,它是1级。project02中引用的log4j:1.2.16对于project01来说它就是2级。所以项目01使用log4j:1.2.17。

声明优先

当资源在相同层级被依赖时(白话就是子模块被引用时,有冲突时)层级相同,上面配置覆盖下面配置。

【示例】project01 引入project02、project03。project02是log4j:1.2.16 、project03是log4j:1.2.12。Maven坐标在引入project02、03的时候,project02坐标写在project03坐标上面,则project02覆盖03的logback。project01使用logback:1.2.16

特殊优先

当同级配置相同资源的多个版本,后配置覆盖前配置。

【示例】项目A引入log4j:1.2.17、log4j:1.2.12(直接引入了2个)。如果log4j:1.2.17写在log4j:1.2.12的上面,则后面版本覆盖前版本。project01 使用log4j:1.2.12。

optional 可选依赖

可选依赖,不给引用者看到我使用了什么坐标。

比如项目A依赖了项目B,如果项目B使用了minio,同时标注了optional = true。则项目A看不到项目B引用的内容了。

exclusions 排除依赖

排除依赖:比如一个项目中有1个okhttp的依赖,引入一个minio,但是minio自己本身引入一个okhttp的依赖。如果我们不想让minio使用自己的okhttp,我们就可以使用exclusions 来排除minio自己的okhttp。

        <dependency>
            <groupId>io.minio</groupId>
            <artifactId>minio</artifactId>
            <version>8.5.2</version>
            <exclusions>
                <exclusion>
                    <groupId>com.squareup.okhttp3</groupId>
                    <artifactId>okhttp</artifactId>
                </exclusion>
            </exclusions>
        </dependency>

scope 作用域

我们先了解一下Maven scope的常见的配置吧

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <scope>runtime</scope>
        </dependency>
        
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>

        <dependency>
            <groupId>com.squareup.okhttp3</groupId>
            <artifactId>okhttp</artifactId>
            <version>4.10.0</version>
            <scope>compile</scope>
        </dependency>

仔细看看,上面Maven坐标,有一个scope标签。

我放上一张图片,IDEA集成的Maven的依赖项。

有的scope是runtime、test、compile,有的没写scope标签

当我们在 Maven 中声明依赖项时,可以使用 <scope> 元素来指定依赖项的作用范围。作用范围决定了依赖项在哪些阶段需要被包含进来,以及在哪些阶段不需要被包含进来。

以下是 Maven 中常见的作用范围:

  • compile:默认作用范围,表示该依赖项在编译、测试和运行时都需要被包含进来。
  • provided:表示该依赖项在编译和测试时需要被包含进来,但在运行时不需要,因为它将由运行环境(Tomcat、Jetty等)提供。案例:JDBC连接信息
  • runtime:表示该依赖项在编译时不需要被包含进来,但在运行时需要被加载。
  • test:表示该依赖项仅在测试时需要被包含进来,不会被打包到最终的构建文件中。
  • system:表示该依赖项类似于 provided,但需要从本地文件系统中指定路径加载。
  • import:表示该依赖项只在 <dependencyManagement> 中使用,用于管理依赖项的版本号,而不是实际引入依赖项。

通过使用不同的作用范围,我们可以更好地管理依赖项,并确保它们在正确的阶段被包含进来。

上文说了很多废话,并不能实际体现在开发中。

Maven scope标签最终体现在不同文件夹中生效:

  • main文件夹下
  • test文件夹下
  • package指令范围

test:仅仅作用在test文件夹下面的类中生效(你就不能再main文件夹下引用相关api了)。比如:junit

compile:默认可省略。作用在整个Maven项目中。

runtime:依赖的含义是指该依赖在运行时需要,但在编译时不需要。比如:jdbc连接的信息、MySQL驱动等。

provitred:【目前开发似乎不需要用到】表示该依赖在编译和测试时需要使用,但在打包时不会包含在最终的构建结果中,而是由运行环境提供。使用provided范围可以帮助我们更好地管理依赖,避免将不必要的依赖打包进去,从而减小构建结果的大小,提高部署效率。

特殊说明:
上述文章均是作者实际操作后产出。烦请各位,请勿直接盗用!转载记得标注原文链接:www.zanglikun.com
第三方平台不会及时更新本文最新内容。如果发现本文资料不全,可访问本人的Java博客搜索:标题关键字。以获取全部资料 ❤