首页 > 编程知识 正文

maven依赖范围,maven中的依赖范围

时间:2023-05-06 21:15:05 阅读:231985 作者:3244

Maven 依赖范围和依赖传递详解

18.10.8 松江图书馆

Maven 依赖范围和依赖传递详解 依赖基本配置依赖范围依赖传递

maven默认依赖体制

maven pom中配置 exclusion标签 手动去除依赖

dependencyManagement和dependencise的区别

依赖基本配置

在pom.xml文件 根元素project下的 dependencies标签中,配置依赖信息,内可以包含多个 dependence元素,以声明多个依赖。每个依赖dependence标签都应该包含以下元素:

groupId, artifactId, version : 依赖的基本坐标, 对于任何一个依赖来说,基本坐标是最重要的, Maven根据坐标才能找到需要的依赖。

这3个属性,可以理解成一个3维的x-y-z坐标,可以通过3个值,来确定一个库中维一个依赖

gooupId 可以理解成一个java的包名(java包名中默认以公司域名倒写),在对应的.m2仓库,它是一个可以有很多层的目录,以. 来进行目录分级

artifactID 可以理解是项目或模块的名称

version 表示不同的版本号

type: 依赖的类型,大部分情况下不需要声明。 默认值为jar

Scope: 依赖范围(compile,test,provided,runtime,system 五种状态)

Optional:标记依赖是否可选

exclusions: 用来排除传递性依赖 其中可配置多个exclusion标签,每个exclusion标签里面对应的有groupId, artifactId, version三项基本元素

example Code:

<project> <groupId>groupA</groupId> <artifactId>artifactA</artifactId> <version>1.0</version> <type>jar<type> <scope>complie<scope> <dependencies> <dependency> <groupId>groupC</groupId> <artifactId>artifactC</artifactId> <version>1.0</version> </dependency> <dependency> <groupId>groupD</groupId> <artifactId>artifactD</artifactId> <version>1.0</version> </dependency> <exclusions> <exclusion> <groupId>T</groupId> <artifactId>jartifactD</artifactId> </exclusion> <exclusion> <groupId>TS</groupId> <artifactId>asm</artifactId> </exclusion> </exclusions> </dependencies> </project> 依赖范围

compile: 编译依赖范围。如果没有指定,就会默认使用该依赖范围。使用此依赖范围的Maven依赖,对于编译、测试、运行三种classpath都有效

system: 系统依赖范围。该依赖与编译、测试、运行三种classpath的关系,和provided依赖范围完全一致。但是,使用system范围依赖时必须通过systemPath元素显式地指定依赖文件的路径。由于此类依赖不是通过Maven仓库解析的,而且往往与本机系统绑定,可能造成构建的不可移植,因此应该谨慎使用。

example code:

<dependencies> <dependency> <groupId>sun.jdk</groupId> <artifactId>tools</artifactId> <version>1.5.0</version> <scope>system</scope> <systemPath>${java.home}/../lib/tools.jar</systemPath> </dependency> </dependencies>

provided: 已提供依赖范围。使用此依赖范围的Maven依赖,对于编译和测试classpath有效,但在运行时无效。典型的例子是servlet-api,编译和测试项目的时候需要该依赖,但在运行项目的时候,由于容器已经提供,就不需要Maven重复地引入一遍(如:servlet-api)。

runtime: 运行时依赖范围。使用此依赖范围的Maven依赖,对于测试和运行classpath有效,但在编译主代码时无效。典型的例子是JDBC驱动实现,项目主代码的编译只需要JDK提供的JDBC接口,只有在执行测试或者运行项目的时候才需要实现上述接口的具体JDBC驱动。

test: 测试依赖范围。使用此依赖范围的Maven依赖,只对于测试classpath有效,在编译主代码或者运行项目的使用时将无法使用此类依赖。典型的例子就是JUnit
,它只有在编译测试代码及运行测试的时候才需要。

依赖传递 maven默认依赖体制

maven引入的传递性依赖机制,一方面大大简化和方便了依赖声明,另一方面,大部分情况下我们只需要关心项目的直接依赖是什么,而不用考虑这些直接依赖会引入什么传递性依赖。但有时候,当传递性依赖造成问题的时候,我们就需要清楚地知道该传递性依赖是从哪条依赖路径引入的。

maven对于依赖相同的资源,默认会做出以下优化:

第一原则:以短路径长度为准

例如,项目A有这样的依赖关系 : A–>B–>C–>X(1.0)、A–>D–>X(2.0),X是A的传递性依赖,但是两条依赖路径上有两个版 本的X,那么哪个X会被maven解析使用呢?两个版本都被解析显然是不对的,因为那会造成依赖重复,因此必须选择一个。maven依赖调解的第一原则:路径最近者优先。该例中X(1.0)的路径长度为3,而X(2.0)的路径长度为2,因此X(2.0)会被解析使用。

第二原则:相同路径长度时,以pom中声明顺序先者为准

依赖调解第一原则不能解决所有问题,比如这样的依赖关系:A–>B–>Y(1.0),A–>C–>Y(2.0),Y(1.0)和Y(2.0)的依赖路径长度是一样的,都为2。那么到底谁会被解析使用呢?在maven2.0.8及之前的版本中,这是不确定的,但是maven2.0.9开始,为了尽可能避免构建的不确定性,maven定义了依赖调解的第二原则:第一声明者优先。在依赖路径长度相等的前提下,在POM中依赖声明的顺序决定了谁会被解析使用。顺序最靠前的那个依赖优胜。

2020.1.14 修改
关于第二条原则,有些歧义

对于在同一个pom文件中,如果引入同一jar包,但不同版本时,后者会覆盖前者,则以后者为准. (当然这种情况一般不会出现)

另外,还有一种解决冲突的办法: 版本锁定原则.

版本锁定原则

面对众多的依赖,版本锁定这一种方式不需要考虑依赖的路径、声明优化等因素,可以直接锁定所依赖jar包的版本,锁定后不会考虑声明顺序及路径。
主要是使用dependencyManageme’标签来是实现

下面以锁定Struts2、Spring、Hibernate版本为例:

<properties><spring.version>4.2.4.RELEASE</spring.version><hibernate.version>5.0.7.Final</hibernate.version><struts.version>2.3.24</struts.version></properties> <!-- 锁定版本,struts2-2.3.24、spring4.2.4、hibernate5.0.7 --><dependencyManagement><dependencies> <dependency> <groupId>org.apache.struts</groupId> <artifactId>struts2-core</artifactId> <version>${struts.version}</version> </dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-context</artifactId><version>${spring.version}</version></dependency> <dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate-core</artifactId> <version>${hibernate.version}</version> </dependency> </dependencies> </dependencyManagement>

注意:在工程中锁定依赖的版本并不代表在工程中添加了依赖, 如果工程需要添加锁定版本的依赖则需要单独添加标签,依然需要使用dependencies标签来引入依赖,只是不必再指定版本号.

<dependencies> <dependency> <groupId>org.apache.struts</groupId> <artifactId>struts2-core</artifactId> <version>${struts.version}</version> </dependency></dependencise> maven pom中配置 exclusion标签 手动去除依赖

场景: 比如,A 和 B 使用需都需要引用c jar包,A引用c的版本为1.0,B引用C的版本为2.0
原则上,我们使用最新版本作为支持,按照maven依赖系统默认原则,其实会引用的是C的1.0版本,此时我可以用exclusion来排除依赖

<dependencies> <dependency> <groupId>A</groupId> <artifactId>A</artifactId> <version>xxx</version> <exclusions> <exclusion> <groupId>C</groupId> <artifactId>C</artifactId> </exclusion> </exclusions> </dependency> <dependency> <groupId>B</groupId> <artifactId>B</artifactId> </dependency> </dependencies> dependencyManagement和dependencise的区别

dependencyManagement标签和denpendencise标签和可作为同级标签,也可作为上下级标签;

同级:dependencyManagement标签功能在于“wxdsb”依赖,denpendencise标签在于“wxdsb和使用”依赖

上下级: 因为dependencyManagement wxdsb一个依赖需要借助denpendencise标签,此时denpendencise标签为子标签

关于“wxdsb”和“wxdsb和使用”依赖的解释:

dependencyManagement标签wxdsb依赖,主要功能为是版本version控制;

尤其在多模构建项目时,在统一的父模块中(父模块配置为<packaging>pom</packaging>),通过dependencyManagement标签,wxdsb依赖,确认了依赖的版本version信息,子模块只需要通过denpendencise标签来引入依赖,不用指定版本,默认用的就是父类版本;
此时要注意: 子项目依赖父类没有wxdsb的依赖,一定要加版本号,此时子类会仓库自行找对应的依赖信息;子项目依赖父类wxdsb的依赖,version版本和父类不同,此时子类也会在仓库中找对应自己的依赖信息;

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。