从第一份工作干到现在,越干遗忘的东西越多,本文用于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范围可以帮助我们更好地管理依赖,避免将不必要的依赖打包进去,从而减小构建结果的大小,提高部署效率。
第三方平台不会及时更新本文最新内容。如果发现本文资料不全,可访问本人的Java博客搜索:标题关键字。以获取最新全部资料 ❤