引用层级越短越有优先
项目A引入logback1.0与项目B,但是项目B引入项目C,项目C引入logback1.1。对于项目A自身的logback1.0来说,它是1级,项目C对于项目A来说它就是3级。所以项目使用logback1.0。
当资源在相同层级被依赖时(白话就是子模块被引用时,就不是第一层级。)层级相同,上面配置覆盖下面的配置。
项目A引入项目B、项目C。项目B本身1级路径是logback1.1 、项目C本身1级路径也是logback1.2。如果项目A引入B、C的时候,项目B坐标写在项目C坐标上面,则项目B覆盖项目C的logback。项目使用logback1.1
当同级配置相同资源的多个版本,后配置覆盖前配置。
项目A引入logback1.1、logback1.2(直接引入了2个)。如果logback1.1写在logback1.2的上面,则后面版本覆盖前版本。项目使用logback1.2。
项目A引入logback1.0,项目B引入logback1.1,项目C引入logback1.2。
可选依赖,不给引用者看到我使用了什么坐标。
比如项目A依赖了项目B,如果项目B使用了minio,同时标注了optional = true。则项目A看到项目B引用的内容了。
<dependency>
<groupId>io.minio</groupId>
<artifactId>minio</artifactId>
<version>8.5.2</version>
<optional>true</optional>
</dependency>
排除依赖:比如一个项目中有1个okhttp的依赖,引入一个minio,但是minio自己本身引入一个okhttp的依赖。如果我们不想让minio使用自己的okhttp,我们就可以使用exclusions 来排除minio自己的okhttp。
<dependency>
<groupId>com.squareup.okhttp3</groupId>
<artifactId>okhttp</artifactId>
<version>4.8.1</version>
</dependency>
<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>
我们先了解一下Maven项目常见的配置吧
<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的依赖项。
这是什么意思,有的没有?有的是runtime、test、compile。到底啥意思呢?
当我们在 Maven 中声明依赖项时,可以使用 <scope>
元素来指定依赖项的作用范围。作用范围决定了依赖项在哪些阶段需要被包含进来,以及在哪些阶段不需要被包含进来。
以下是 Maven 中常见的作用范围:
compile
:默认作用范围,表示该依赖项在编译、测试和运行时都需要被包含进来。provided
:表示该依赖项在编译和测试时需要被包含进来,但在运行时不需要,因为它将由运行环境(Tomcat、Jetty等)提供。runtime
:表示该依赖项在编译时不需要被包含进来,但在运行时需要被加载。test
:表示该依赖项仅在测试时需要被包含进来,不会被打包到最终的构建文件中。system
:表示该依赖项类似于 provided
,但需要从本地文件系统中指定路径加载。import
:表示该依赖项只在 <dependencyManagement>
中使用,用于管理依赖项的版本号,而不是实际引入依赖项。通过使用不同的作用范围,我们可以更好地管理依赖项,并确保它们在正确的阶段被包含进来。
上文说了很多废话,并不能实际体现在开发中。
Maven scope标签最终体现在不同文件夹中生效:
test:仅仅作用在test文件夹下面的类中生效。比如:junit
compile:默认可省略。作用在整个Maven项目中。
runtime:仅仅作用于在package指令。比如:jdbc连接的信息等
provitred:除了package作用在其他范围内。比如:servlet-api。