持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第18天,点击查看活动详情
哈喽,大家好!我是Why,一名在读学生,目前刚刚开始进入自己的编程学习生涯。虽然学习起步较晚,但我坚信做了才有0或1的可能。学了一段时间以后也是选择在掘金上分享自己的日常笔记,也希望能够在众多道友的大家庭中打成一片。 本文主要讲解Maven的传递性和依赖性,如果大家读后觉得有用的话,还请大家多多支持博主:欢迎 ❤️点赞👍、收藏⭐、留言💬 ✨✨✨个人主页:JinHuan
💎Maven的传递性和依赖性
🎯1 依赖管理
就是对项目中jar 包的管理。可以在pom文件中定义jar包的GAV坐标,管理依赖。依赖声明主要包含如下元素:
<dependency>
<groupId></groupId>
<artifactId></artifactId>
<version></version>
<scope></scope>
</dependency>
Maven依赖管理的原理分析
🎯2 依赖范围(scope标签的取值)
| 依赖范围(Scope) | 对于主代码(classpath) | 对于测试代码classpath有效 | 被打包,对于运行时classpath有效 | 栗子 |
|---|---|---|---|---|
| compile | Y | Y | Y | log4j |
| tets | - | Y | - | junit |
| provided | Y | Y | - | servlet-api |
| runtime | - | - | Y | JDBC Driver Implementation |
🌈2.1 compile-默认值
编译范围,默认scope,在工程环境的 classpath(编译环境)和打包(如果是WAR包,会包含在WAR包中)时候都有效。
🌈2.2 provided
容器或JDK已提供范围,表示该依赖包已经由目标容器(如tomcat)和JDK提供,只在编译的classpath中加载和使用,打包的时候不会包含在目标包中 。最常见的是j2ee规范相关的servlet-api和jsp-api等jar包,一般由servlet容器提供,无需在打包到war包中,如果不配置为provided,把这些包打包到工程war包中,在tomcat6以上版本会出现冲突无法正常运行程序(版本不符的情况)。
🌈2.3 runtime
一般是运行和测试环境使用,编译时候不用加入classpath,打包时候会打包到目标包中。一般是通过动态加载或接口反射加载的情况比较多。也就是说程序只使用了接口,具体的时候可能有多个,运行时通过配置文件或jar包扫描动态加载的情况。典型的包括:JDBC驱动等。
🌈2.4 test
测试范围,一般是单元测试场景使用,在编译环境加入classpath,但打包时不会加入,如junit等。
🌈2.5 system(一般不用,不同机器可能不兼容)
系统范围,与provided类似,只是标记为该scope的依赖包需要明确指定基于文件系统的jar包路径。因为需要通过systemPath指定本地jar文件路径,所以该scope是不推荐的。如果是基于组织的,一般会建立本地镜像,会把本地的或组织的基础组件加入本地镜像管理,避过使用该scope的情况。
🎯3 依赖传递
🌈3.1 直接依赖和间接依赖
如果B中使用A,C中使用B,则称B是C的直接依赖,而称A是C的间接依赖。 C->B B->A C直接依赖B C间接依赖A
🌈3.2 依赖范围对传递依赖的影响
| compile | test | provided | runtime | |
|---|---|---|---|---|
| compile | compilew | - | - | runtime |
| test | test | - | - | test |
| provided | provided | - | provided | provided |
| runtimes | runtime | - | - | runtime |
左边第一列表示第一直接依赖范围 上面第一行表示第二直接依赖范围 中间的交叉单元格表示传递性依赖范围。 定义在标签
总结: (1) 当第二依赖的范围是compile的时候,传递性依赖的范围与第一直接依赖的范围一致。 (2) 当第二直接依赖的范围是test的时候,依赖不会得以传递。 (3) 当第二依赖的范围是provided的时候,只传递第一直接依赖范围也为provided的依赖,且传递性依赖的范围同样为 provided; (4) 当第二直接依赖的范围是runtime的时候,传递性依赖的范围与第一直接依赖的范围一致,但compile例外,此时传递的依赖范围为runtime;
🎯4 依赖冲突
(1) 如果直接与间接依赖中包含有同一个坐标不同版本的资源依赖,以直接依赖的版本为准(就近原则) (2) 如果直接依赖中包含有同一个坐标不同版本的资源依赖,以配置顺序下方的版本为准(就近原则)
🎯5 可选依赖
true/false 用于设置是否可选,也可以理解为jar包是否向下传递。 在依赖中添加optional选项决定此依赖是否向下传递,如果是true则不传递,如果是false就传递,默认为false。
🎯6 排除依赖
Maven 的传递依赖能自动将间接依赖引入项目中来,这样极大地简化了项目中的依赖管理,但是有时候间接依赖的关联包可以因为版本或其他原因,并不是我们想要的版本,那该怎么办呢? 这种做法就是排除依赖。那怎么实现排除依赖呢?实现排除依赖还是比较简单的,在直接依赖的配置里面添加 exclusions→exclusion 元素,指定要排除依赖的 groupId 和 artifactId 就行,如下面代码所示。
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId> <version>4.11</version>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.hamcrest</groupId>
<artifactId>hamcrest-core</artifactId>
</exclusion>
</exclusions>
</dependency>
注意:排除依赖包中所包含的依赖关系,不需要添加版本号。
🤡写在最后
关于Maven的讲解就到这里了,关于Maven的安装运行使用等问题的欢迎大家评论区留言,博主看到后会一一回复。 最后别忘啦支持一下博主哦,求三连!❤️❤️❤️