【Maven】依赖范围、依赖传递、依赖排除、依赖原则、依赖继承
- 依赖范围
- 依赖传递
- 依赖排除
- 依赖原则
- 依赖继承
依赖范围
在Maven
中,依赖范围(Dependency Scope)
用于控制依赖项在编译、测试和运行时的可见性和可用性。通过指定适当的依赖范围,可以在不同的构建和执行环境中控制依赖项的加载和使用。
compile(默认)
:该依赖项在编译、测试和运行时都可用。这是大多数依赖项的默认范围。
test
:该依赖项只在测试编译和测试运行期间可用,不会被导入到最终的构件中。
provided
:该依赖项由 JDK 或容器(如 Tomcat)提供,编译和测试时可用,但在打包构建产物时不会包含它。需要确保在目标环境中该依赖项可以被提供。
runtime
:该依赖项在编译时不可用,但在运行时和测试时可用。例如,JDBC 驱动程序通常以此范围进行声明,因为编译时并不需要 JDBC 驱动程序,但在运行时需要它来连接数据库。
以下示例演示了如何指定依赖范围:
<dependencies>
<dependency>
<groupId>com.example</groupId>
<artifactId>my-library</artifactId>
<version>1.0.0</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
</dependencies>
依赖传递
在Maven
中,依赖传递(Dependency Transitivity)
是指当一个项目依赖于其他项目时,它会自动获取这些依赖项所依赖的其他项目。
依赖传递是Maven
的重要特性之一,它使得在项目中声明的依赖项可以自动解析和下载其所依赖的其他库,并将其包含在项目构建中。
例如,如果项目 A 依赖于项目 B,而项目 B 又依赖于项目 C,那么在Maven
构建过程中,项目 A 将自动获取项目 B 和项目 C 的依赖。这样,你不需要手动在项目 A 中声明对项目 C 的依赖,Maven
将自动完成这个过程。
依赖传递还可以处理依赖冲突。当多个依赖项声明了相同的库但版本不同时,Maven
会使用一定的规则来解决冲突。通常,它会选择一个合适的版本来满足所有依赖项,并将其包含在最终的构建结果中。也可以通过显式地声明特定版本来覆盖冲突解析过程。
下面是一个例子:
spring-boot-starter
依赖了下面4个jar
包,所以项目也会自动下载引入下面的4个包。
依赖排除
在Maven
中,依赖排除(Dependency Exclusion)
是指从传递的依赖关系中排除某个特定的依赖项。这可以用于解决依赖冲突或避免引入不需要的依赖项。
有时候,一个项目可能依赖于某个库,而该库本身又依赖于其他库。但是,由于项目已经显式声明了对其他库的依赖,可能希望排除传递依赖关系中的某个库,以避免版本冲突或避免引入不需要的库。
通过使用 <exclusions>
元素,可以在Maven
的依赖声明中指定要排除的依赖项。下面是例子:
<project>
<dependencies>
<dependency>
<groupId>com.example</groupId>
<artifactId>project-a</artifactId>
<version>1.0.0</version>
<exclusions>
<exclusion>
<groupId>com.example</groupId>
<artifactId>unwanted-library</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
</project>
依赖原则
依赖的原则:它是为了解决工程模块之间的jar
包冲突的问题的,我们无法设置,maven
有默认的原则,我们需要了解。
当多个依赖项引入了相同的库但不同的版本时,Maven
使用一套规则来解决依赖冲突。通常情况下,较高版本的库会被选择,但也可以使用 <dependencyManagement>
和 <exclusions>
等元素来显式地解决依赖冲突问题。
依赖继承
如果项目需要将各个模块的 junit 版本统一为 4.9,那么到各个工程中手动修改无疑是非常不可取的。
使用继承机制就可以将这样的依赖信息统一提取到父工程模块中进行统一管理。
创建父工程和创建一般的 Java 工程操作一致,唯一需要注意的是:打包方式处要设置为 pom。
而在子工程中只需要引入父工程的工程坐标就可以了。
<parent>
<!-- 父工程坐标 -->
<groupId>...</groupId>
<artifactId>Parent</artifactId>
<version>0.0.1-SNAPSHOT</version>
<!-- 指定从当前子工程的pom.xml文件出发,查找父工程的pom.xml的路径 -->
<relativePath>../Parent/pom.xml</relativePath>
</parent>
此时如果子工程的 groupId 和 version 和父工程重复则可以删除。
将 Parent 项目中的 dependencies 标签,用 dependencyManagement 标签括起来。
<dependencyManagement>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.9</version>
<scope>test</scope>
</dependency>
</dependencies>
</dependencyManagement>
在子项目中重新指定需要的依赖,删除范围和版本号。
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
</dependency>
</dependencies>