Maven详解(五)------ 坐标的概念以及依赖管理
我们知道maven能帮我们管理jar包,那么它是怎么管理的呢?这篇博客我们来详细介绍。
1、什么是坐标?
①、数学中的坐标
在平面上,使用 X 、Y 两个向量可以唯一的定位平面中的任何一个点
在空间中,使用 X、Y、Z 三个向量可以唯一的定位空间中的任意一个点
②、Maven 中的坐标
俗称 gav:使用下面三个向量子仓库中唯一定位一个 Maven 工程
在项目中的 pom.xml 文件中,我们可以看到下面gav的定义:
1、groupid:公司或组织域名倒序
<groupid>com.ys.maven</groupid>
2、artifactid:模块名,也是实际项目的名称
③、Maven 坐标和仓库,jar 包的关系
什么是仓库,后面我们会详细讲解,现在你只需要知道是Maven 用来存放 jar 包的地方。
那么依照上面定义的 gav,我们执行 mvn -install 命令,会出现什么情况呢?
首先进入到我们第二篇博客 Maven 的安装配置 ,通过 settings.xml 文件配置的仓库目录。
将我们上面配置的 gav 向量组合起来就是目录:
com/ys/maven/Maven_05/0.0.1-SNAPSHOT/Maven_05-0.0.1-SNAPSHOT.jar
其次,我们观察打出来的 jar 包:
Maven_05-0.0.1-SNAPSHOT.jar
也就是 artifactid-version.jar
2、什么是依赖?
什么是 依赖?相信有过一定开发经验的人知道,每当我们需要使用某个框架时,比如 SpringMVC,那么我们需要导入相应的 jar 包,但是手动导入包的时候,往往会漏掉几个 jar 包,那么在使用该框架的时候系统就会报错。那么我们就说导入的包与未导入的包存在依赖关系。而使用 Maven,我们只需要在 pom.xml 文件中进行相应的配置,它就会帮助我们自动管理 jar 包之间的依赖关系。那么它是怎么管理的呢,接下来我们会详细讲解。
3、依赖的详细配置
我们以 Junit 为例,在 pom.xml 文件中进行详细而完整的配置。
<project>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<type>...</type>
<scope>...</scope>
<optional>...</optional>
<exclusions>
<exclusion>
<groupId>...</groupId>
<artifactId>...</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
</project>
①、dependencies:一个 pom.xml 文件中只能存在一个这样的标签。用来管理依赖的总标签。
②、dependency:包含在dependencies标签中,可以有无数个,每一个表示一个依赖
③、groupId,artifactId和version:依赖的基本坐标,对于任何一个依赖来说,基本坐标是最重要的,Maven根据坐标才能找到需要的依赖。
④、type:依赖的类型,对应于项目坐标定义的packaging。大部分情况下,该元素不必声明,其默认值是jar。
⑤、scope:依赖的范围,默认值是 compile。后面会进行详解。
⑥、optional:标记依赖是否可选。
⑦、exclusions:用来排除传递性依赖,后面会进行详细介绍。
4、依赖的范围 scope
一般情况下,我们对前面三个依赖用的比较多。下面的主程序表示maven 目录结构 src/main/java.测试程序目录结构为:src/test/java
1、compile 范围依赖
对主程序是否有效:有效
对测试程序是否有效:有效
是否参与打包:参与
是否参与部署:参与
典型例子:log4j
2、test 范围依赖
对主程序是否有效:无效
对测试程序是否有效:有效
是否参与打包:不参与
是否参与部署:不参与
典型例子:Junit
3、provided 范围依赖
对主程序是否有效:有效
对测试程序是否有效:有效
是否参与打包:不参与
是否参与部署:不参与
典型例子:servlet-api.jar,一般在发布到 服务器中,比如 tomcat,服务器会自带 servlet-api.jar 包,所以provided 范围依赖只在编译测试有效。
4、runtime 范围依赖:在测试、运行的时候依赖,在编译的时候不依赖。例如:JDBC驱动,项目代码只需要jdk提供的jdbc接口,只有在执行测试和运行项目的时候才需要实现jdbc的功能。
接下来我们举几个例子在工程中实际去理解:
test 依赖和 compile 依赖的区别:
①、首先我们在 pom.xml 文件中配置,Junit 的 test 依赖
②、我们在主程序中去导入 Junit 的包,然后进行 mvn -compile 编译,很明显,test 范围的在主程序中无效,故编译会报错。
我们在 src/main/java 包下新建 MavenTest.java,并导入 Junit 包
然后执行 mvn -compile 操作,如下图报错信息:
③、我们将 Junit 的依赖范围改为 compile,然后执行 mvn -compile
发现 mvn -compile 没有报错了。
4、依赖的传递
比如我们创建三个Maven 工程,maven-first,maven-second以及maven-third,而third依赖于second,second又依赖于first,那么我们说 second 是 third 的第一直接依赖,first是second的第二直接依赖。而first是third的间接依赖。
依赖之间的传递如下图:第一列表示第一直接依赖,第一行表示第二直接依赖
总结:
1、当第二依赖的范围是compile的时候,传递性依赖的范围与第一直接依赖的范围一致。
2、当第二直接依赖的范围是test的时候,依赖不会得以传递。
3、当第二依赖的范围是provided的时候,只传递第一直接依赖范围也为provided的依赖,且传递性依赖的范围同样为 provided;
4、当第二直接依赖的范围是runtime的时候,传递性依赖的范围与第一直接依赖的范围一致,但compile例外,此时传递的依赖范围为runtime;
我们这里举个例子来看:
①、第二依赖范围是 test
Maven_first 的pom.xml 文件如下:
然后Maven_second依赖Maven_fisrt,Maven_third依赖Maven-second,其pom.xml 文件如下:
Maven_second的 pom.xml
Maven_third的 pom.xml
我们发现在 Maven_third和 Maven_second 都没有 Maven_first 引入的 Junit 包,正好符合上面总结的第二点:当第二直接依赖的范围是test的时候,依赖不会得以传递。
②、第二依赖范围是 compile
如果我们将 Maven_first 的Junit 改为 compile,那么将会符合上面总结的第一点:当第二依赖的范围是compile的时候,传递性依赖的范围与第一直接依赖的范围一致。
5、依赖的排除
如果我们在当前工程中引入了一个依赖是 A,而 A 又依赖了 B,那么 Maven 会自动将 A 依赖的 B 引入当前工程,但是个别情况下 B 有可能是一个不稳定版,或对当前工程有不良影响。这时我们可以在引入 A 的时候将 B 排除。
比如:我们在Maven_first 中添加 spring-core,maven 会自动将 commons-logging添加进来,那么由于 Maven_second 是依赖 Maven_first 的,那么 Maven_second 中将存在 spring-core(自带了commons-logging),这时候我们不想要 commons-logging,那该怎么办呢?我们上面第二大点提到了:
exclusions:用来排除传递性依赖
Maven_first 的 pom.xml 文件
由于 Maven_second 依赖 Maven_second,故Maven_second 存在 spring-core 包
如何排除呢?我们在 Maven_second 的 pom.xml 文件中添加如下代码:
再次查看工程:Maven_second 的 commons-logging 已经移除了
6、依赖的冲突
在maven中存在两种冲突方式:一种是跨pom文件的冲突,一致是同一个pom文件中的冲突。
①、跨 pom 文件,路径最短者优先。比如我们在 Maven_first 中的 Junit 是4.9版本的,Maven_second 中的 Junit 是4.8版本的,那么Maven_third 中的 Junit 将会是那个版本呢?
由上图我们可以看出,由于 Maven_second 是 Maven_third 的直接依赖,明显相比于 Maven_first 路径要短,所以 Maven_third 的 Junit 版本与 Maven_second 保持一致。
②、同一个pom.xml 文件,先申明者优先。
看 Maven_second
7、可选依赖
Optional标签标示该依赖是否可选,默认是false。可以理解为,如果为true,则表示该依赖不会传递下去,如果为false,则会传递下去。
我们是在 Maven_second 的 pom 文件中设定 Junit 不可传递,那么Maven_third 工程中将不会有来自 Maven_second 的 Junit 的传递。
Maven详解(五)------ 坐标的概念以及依赖管理的更多相关文章
- .NET DLL 保护措施详解(五)常规条件下的破解
为了证实在常规手段破解下能有效保护程序核心功能(演示版本对AES加解密算法及数据库的密钥(一段字符串)进行了保护),特对此DLL保护思路进行相应的测试,包含了反编译及反射测试,看是否能得到AES加解密 ...
- 转:Windows下的PHP开发环境搭建——PHP线程安全与非线程安全、Apache版本选择,及详解五种运行模式。
原文来自于:http://www.ituring.com.cn/article/128439 Windows下的PHP开发环境搭建——PHP线程安全与非线程安全.Apache版本选择,及详解五种运行模 ...
- python设计模式之迭代器与生成器详解(五)
前言 迭代器是设计模式中的一种行为模式,它提供一种方法顺序访问一个聚合对象中各个元素, 而又不需暴露该对象的内部表示.python提倡使用生成器,生成器也是迭代器的一种. 系列文章 python设计模 ...
- pika详解(五)登录认证及connectionParameters
pika详解(五)登录认证及connectionParameters 本文链接:https://blog.csdn.net/comprel/article/details/94662916 版权 pi ...
- Maven详解
一.前言 以前做过的项目中,没有真正的使用过Maven,只知道其名声很大,其作用是用来管理jar 包的.最近一段时间在项目过程中使用Maven,用Maven构建的web项目,其项目结构只停留在 ...
- [Maven]Maven详解
转自:http://www.cnblogs.com/hongwz/p/5456578.html 一.前言 以前做过的项目中,没有真正的使用过Maven,只知道其名声很大,其作用是用来管理jar ...
- Maven详解【面试+工作】 各种安装 没用
1 Maven介绍1.1 项目开发中遇到的问题 1.都是同样的代码,为什么在我的机器上可以编译执行,而在他的机器上就不行? 2.为什么在我的机器上可以正常打包,而配置管理员却打不出来? 3.项目组加入 ...
- Maven详解(非原创)
文章大纲 一.maven功能介绍二.maven整合javaweb案例三.私服应用(了解)四.总结五.相关资料下载六.参考文章 一.maven功能介绍 1. maven基本介绍 Maven的Apac ...
- Maven详解之聚合与继承
说到聚合与继承我们都很熟悉,maven同样也具备这样的设计原则,下面我们来看一下Maven的pom如何进行聚合与继承的配置实现. 一.为什么要聚合? 随着技术的飞速发展和各类用户对软件的要求越来越高, ...
随机推荐
- php工作两年了。。。
对于一个快要毕业的人来说,我相信大部分人都是迷茫的,我也一样但是迷茫的一塌糊涂完全不知道以后自己能干什么. 2014年底,某某培训机构来到学校进行招生.反正在对方的一阵忽悠之下我是蠢蠢欲动,但是当时的 ...
- poj_3258:River Hopscotch(二分)
题目链接 L为N+2块石子中最右边石子位置,0最左,M为可移除块数,求移除后相邻石子可达到的最大距离. #include<iostream> #include<cstdio> ...
- 开源个.NetCore写的 - 并发请求工具PressureTool
本篇和大家分享的是一个 并发请求工具,并发往往代表的就是压力,对于一些订单量比较多的公司这种情况很普遍,也因此出现了很多应对并发的解决方案如:分布式,队列,数据库锁等: 对于没有遇到过或者不可能线上来 ...
- tensorflow Sigmoid 应用
1.函数 函数:f(z) = 1 / (1 + exp( − z)) 导数:f(z)' = f(z)(1 − f(z)) 2.tensorflow实现 #!/usr/bin/env python # ...
- html5图片上传时IOS和Android均显示摄像头拍照和图片选择
最近在做信开发时,发现<input type="file" />在IOS中可以拍照或从照片图库选择,而Android系统则显示资源管理器,无拍照选项,网上查找资料,改为 ...
- CentOS 下mysql ERROR&n…
CentOS 下mysql ERROR 1045: Access denied for user: 'root@localhost' (Using password: NO) 描述:在操作数据库时会出 ...
- hdu 6045 Is Derek lying?(思维推导)
Problem Description Derek and Alfia are good friends.Derek is Chinese,and Alfia is Austrian.This sum ...
- discuz相关总结
1.dz的下载安装 进入discuz官方网站下载discuz安装包:拷贝出其中的upload目录,重命名为discuz,将discuz目录上传至linux公网服务器: 配置web服务器,nginx或者 ...
- ARP与RARP协议及arp脚本
1.什么是ARP与RARP协议 地址解析协议,即ARP(Address Resolution Protocol),是根据IP地址获取物理地址的一个TCP/IP协议. 在⽹络通讯时,源主机的应⽤程序知道 ...
- IntelliJ IDEA(2017.2)安装和破解(转)
如果有一定的经济基础,请支持正版,这里提供破解方法. 一.下载并安装, IntelliJ IDEA的官网:https://www.jetbrains.com 二.破解. 百度下载一个 Jetbrain ...