引言

maven的依赖特性很多很杂,这里大概总结一下,maven的依赖特性主要是依赖范围和传递依赖,前者会影响后者,这篇文章会介绍传递依赖的传递原则,出现冲突传递依赖默认如何处理,我们自己可以怎么处理等内容

依赖范围

依赖范围会影响传递性依赖,同时也会影响项目构建任务中使用的classpath。

Maven有以下6种依赖范围:

compile

这是默认范围。如果没有指定,就会使用该依赖范围。编译依赖对项目所有的classpath都可用。此外,编译依赖会传递到依赖的项目。

provided

和compile范围很类似,但provided范围表明你希望由JDK或者某个容器提供运行时依赖。例如,当使用Java EE构建一个web应用时,你会设置对Servlet API和相关的Java EE APIs的依赖范围为provided,因为web容器提供了运行时的依赖。provided依赖只对编译和测试classpath有效,并且不能传递。

runtime

runtime范围表明编译时不需要依赖,而只在运行时依赖。此依赖范围对运行和测试classpath有效,对编译classpath无效。

test

test范围表明使用此依赖范围的依赖,只在编译测试代码和运行测试的时候需要,应用的正常运行不需要此类依赖。

system

系统范围与provided类似,不过你必须显式指定一个本地系统路径的JAR,此类依赖应该一直有效,Maven也不会去仓库中寻找它。



一些说明:

  1. runtime类型的比较少见,这里可以举一个例子,就是JDBC的驱动实现类(mysql-connector-java),我们在编写JDBC相关代码时,都是使用的JDBC的接口,基于接口编程,因此编译上不会报错,但在实际运行时,肯定是要实现类去做的
  2. 对于system类型运行时打包不会打进去,想要打进去可以使用插件,另一种方式是不要使用system得scope,直接将jar打到私服,然后依赖

传递依赖

传递依赖基于要传递的依赖scope为compile,runtime,system的依赖范围,scope为test和provided不会传递依赖 ,此外传递性依赖的嵌套深度没有任何限制,只是在出现循环依赖时会报错。下图是传递依赖时的scope变化,第一列表示直接依赖,第一行表示间接依赖的Scope

举例说明:

A–>B–>C。当前项目为A,A依赖于B,B依赖于C。知道B在A项目中的scope,那么怎么知道C在A中的scope呢?

答案是:

当C是test或者provided时,C直接被丢弃,A不依赖C;

否则A依赖C,C的scope继承于B的scope。

基本传递依赖

传递依赖指的是A依赖B,B依赖C,D,F等,那么A也同时依赖C,D,F

传递依赖冲突-依赖调解

当项目中出现多个版本构件依赖的情形,依赖调解决定最终应该使用哪个版本,主要依赖于两个原则(注意优先第一个原则,两个原则有优先级之分),这是maven自动进行的

  1. 短路径优先原则

    A依赖B工程,B工程依赖C-1.jar,A工程依赖C-2.jar,那么A工程最终依赖的是C-2.jar,因为这条依赖链最短

  2. 第一声明原则

    A依赖B工程,B工程依赖S-1.jar,A工程依赖C工程,C工程依赖S-2.jar,那么A工程最终依赖的是S-1.jar,因为在依赖链长度相同时,A工程在pom文件中先声明依赖B工程,先声明指的是在A工程pom文件中的dependencies标签下,B工程的dependency写在C工程前面

    注意:直接在pom里面依赖同一个jar包的不同版本,在后面写的会实际依赖,和第一声明原则相反

exclusions元素排除依赖

当项目中某个传递依赖我们不需要时可以使用标签进行排除,即排除指定的间接依赖,注意这个排除指的是排除本身自带的依赖jar,转而依赖项目整体依赖的jar

      <dependency>
<groupId>com.alibaba</groupId>
<artifactId>dubbo</artifactId>
<version>2.5.3</version>
<exclusions>
<exclusion>
<artifactId>spring</artifactId>
<groupId>org.springframework</groupId>
</exclusion>
</exclusions>
</dependency>

可选依赖-Optional Dependencies

简单来说就是不会传递依赖的意思,他不会传递给依赖他的项目

当自己开发一个供别人使用的jar包,项目依赖于多个模块,完成不同功能,各个功能相互独立,那么当第三方使用我的jar包时可以排除他不需要的依赖功能jar包,保留其需要的,这需要"我"在pom中配置依赖的可选性

<dependency>
<groupId>sample.ProjectB</groupId>
<artifactId>Project-B</artifactId>
<version>1.0</version>
<scope>compile</scope>
<optional>true</optional> <!-- value will be true or false only -->
</dependency>
</dependencies>

假设以上配置是项目A的配置,即:Project-A --> Project-B。在编译项目A时,是可以正常通过的。

如果有一个新的项目X依赖A,即:Project-X -> Project-A。此时项目X就不会依赖项目B了。如果项目X用到了涉及项目B的功能,那么就需要在pom.xml中重新配置对项目B的依赖。

maven多环境打包配置

开发中往往有很多套环境需要打包时来回切换非常的麻烦,也很容易出错,maven其实提供了不同环境打包的方案,配置方法如下:

在resource下建立3套环境的配置文件,如下图所示:

xml配置文件依然引用的是resource下的那3个配置文件,要求打包时将要使用环境的3个配置文件转移到resource目录下,当前xml是报错的,因为resource下并无配置文件

pom文件配置

配置profiles标签

有几套环境配置几套,<profile.path>标签代表环境所在目录,标签为true代表默认使用该套环境

<!-- maven分环境打包 -->
<profiles>
<profile>
<!-- 开发环境 -->
<id>dev</id>
<properties>
<profile.path>/dev</profile.path>
</properties>
<activation>
<activeByDefault>true</activeByDefault><!-- 默认激活该profile节点-->
</activation>
</profile>
<profile>
<!-- 测试环境 -->
<id>test</id>
<properties>
<profile.path>/test</profile.path>
</properties>
</profile>
<profile>
<!-- 生产环境 -->
<id>online</id>
<properties>
<profile.path>/online</profile.path>
</properties>
</profile>
</profiles>

配置标签下的标签

<build>
<!-- 配置配置文件 -->
<resources>
<!-- 配置这个resource是为了排除在class目录下生成3个环境目录及配置文件-->
<resource>
<directory>src/main/resources</directory>
<excludes>
<exclude>**/dev/**</exclude>
<exclude>**/test/**</exclude>
<exclude>**/online/**</exclude>
</excludes>
</resource>
<!-- 这个是在打包时指定打包使用的环境 -->
<resource>
<directory>src/main/resources/${profile.path}</directory>
<filtering>true</filtering>
</resource>
</resources>
</build>

打包时选择环境

勾选要使用的环境,执行打包命令即可

参考

Maven依赖中的scope详解

Maven入门-4.Maven的依赖

《Maven官方文档》-Maven依赖机制简介

可选依赖及排除依赖

maven的依赖特性的更多相关文章

  1. maven学习笔记三(依赖特性,作用域)

    上一章中  我们看到了添加了个junit的依赖包.那么maven中想添加依赖的jar包我们只需要配置相应的dependency就行.例如: <dependency> <groupId ...

  2. Maven入门-4.Maven的依赖

    1.Maven的依赖1.1 添加依赖1.2 依赖范围(sope)依赖范围与classpath的关系1.3 依赖的传递性1.2.1 依赖传递性的冲突问题1. 第一种情况2. 第二种情况1.2.2 通过e ...

  3. Maven的依赖管理

    我们知道dependencies是可以被继承的,这个时候我们就想到让我们的发生了共用的依赖元素转移到parent中,这样我们又进一步的优化了配置.可是问题也随之而来,如果有一天我创建了一个新的模块,但 ...

  4. Maven的依赖机制介绍

    以下内容引用自https://ayayui.gitbooks.io/tutorialspoint-maven/content/book/maven_manage_dependencies.html: ...

  5. [转]使用Maven添加依赖项时(Add Dependency)时,没有提示项目可用,并且在Console中,输出: Unable to update index for central|http://repo1.maven.org/maven2 。

    使用Maven添加依赖项时(Add Dependency)时,没有提示项目可用,并且在Console中,输出: Unable to update index for central|http://re ...

  6. Maven间接依赖冲突解决办法

    如果项目中maven依赖太多,由于还有jar之间的间接依赖,所以可能会存在依赖冲突.依赖冲突大部分都是由于版本冲突引起的,查看maven的依赖关系,可以找到引起冲突的间接依赖 如上图,通过Depend ...

  7. maven 检查依赖冲突和版本冲突

    maven 检查依赖冲突和版本冲突   在项目发布的时候,一般都需要进行依赖冲突检查或者重复类的检查,这个时候我一般会使用下面的两个命令:   1 2 3 mvn -U clean package - ...

  8. maven可选依赖(Optional Dependencies)和依赖排除(Dependency Exclusions)

    我们知道,maven的依赖关系是有传递性的.如:A-->B,B-->C.但有时候,项目A可能不是必需依赖C,因此需要在项目A中排除对A的依赖.在maven的依赖管理中,有两种方式可以对依赖 ...

  9. Maven的依赖范围

    Maven的依赖构件包含一个依赖范围属性,这个属性描述的是三套classpath的控制,即编译.测试.运行. 举个例子Junit依赖只是在测试范围(classpath)使用,而在运行的时候不使用,还有 ...

随机推荐

  1. 自动化测试系列:将常用的Android adb shell 命令行封装为C#静态函数

    更多原创测试技术文章同步更新到微信公众号 :三国测,敬请扫码关注个人的微信号,感谢! 简介:adb命令是常用的Android命令行,自动化.代码调试.手工排查问题都会用的到,这里将常用的一些命令行封装 ...

  2. react初探(一)之JSX、状态(state)管理、条件渲染、事件处理

    前言: 最近收到组长通知我们项目组后面新开的项目准备统一技术栈为react,目前我的情况是三大框架只会angular和Vue.在实际项目中只使用过一次angular5,其余项目都是使用Vue写的.写篇 ...

  3. Python交互K线工具 K线核心功能+指标切换

    Python交互K线工具 K线核心功能+指标切换 aiqtt团队量化研究,用vn.py回测和研究策略.基于vnpy开源代码,刚开始接触pyqt,开发界面还是很痛苦,找了很多案例参考,但并不能完全满足我 ...

  4. 素数问题(JAVA)

    http://wenda.haosou.com/q/1371348579062596 http://blog.csdn.net/liukehua123/article/details/5482854

  5. sentinel详解

    https://segmentfault.com/a/1190000002680804 sentinel端口 port #工作路径 dir "/usr/local/redis-6380&qu ...

  6. 对mybatis的Handler 从使用角度介绍

    最近在开发中,涉及到了讲数据库查询的类型,直接转为java需要的类型. 由于对handler 理解不到位 和 使用不当.躺了一些坑. 主要涉及的有2种. 1.varchar 转 List<T&g ...

  7. Tensorflow 报错:tensorflow.python.framework.errors_impl.InternalError: Failed to create session.

    问题描述 IDE:pycharm,环境中安装tensorflow-gpu 1.8.0 ,Cuda9 ,cudnn 7,等,运行代码 报错如下 tensorflow.python.framework.e ...

  8. Vue2全家桶之二:vue-router(路由)详细教程,看这个就够了

     作者:东西里本文转载于:https://www.jianshu.com/p/514c7588e877来源:简书 转载仅供自己日后看方便.  由于Vue在开发时对路由支持的不足,于是官方补充了vue- ...

  9. XFS文件系统的备份和恢复

    1.工具 XFS文件系统提供了xfsdump和xfsrestore来协助备份.恢复XFS文件系统中的数据,xfsdump按inode顺序来备份XFS文件系统,备份时不需要卸载文件系统,备份和恢复的过程 ...

  10. day2作业

    购物车(两个程序)用户入口1商品信息存在文件里2已购商品,余额记录商家入口2可以添加商品,修改商品价格