Maven依赖理解

  • 1 简介
  • 2 依赖的配置
  • 3 依赖的范围
  • 4 传递性依赖
    • 4.1 传递性依赖和依赖调解
  • 5 依赖调解
  • 6 可选依赖
  • 7 总结
  • 8 下载

1 简介

 在Maven项目中,有一个核心文件pom.xml。POM项目对象模型定义了项目的基本信息,用于描述心目如何构建,声明项目依赖。
 没有任何的实际Java代码,我们就能顶一个Maven项目的POM,这体现了Maven的一大优点,它能让项目对象模型最大程度地与实际代码相互独立,即解耦,或者正交性。这在很大程度上避免了Java代码和POM代码的相互影响。比如当项目需要升级版本时,只需要修改POM,而不需要更待Java代码;而在POM稳定之后,日常的Java代码开发工作基本不涉及POM的修改。
下面的pom文件即为一个xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.0.3.RELEASE</version><relativePath/> <!-- lookup parent from repository --></parent><groupId>com.example</groupId><artifactId>screenshot</artifactId><version>0.0.1-SNAPSHOT</version><name>screenshot</name><description>Demo project for Spring Boot</description><packaging>war</packaging><properties><java.version>1.8</java.version></properties><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId><!-- 移除嵌入式tomcat插件 --><exclusions><exclusion><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-tomcat</artifactId></exclusion></exclusions></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId></dependency><dependency><groupId>javax.servlet</groupId><artifactId>javax.servlet-api</artifactId><version>3.1.0</version><scope>provided</scope></dependency></dependencies><build><finalName>screenshot</finalName><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId></plugin><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-compiler-plugin</artifactId><configuration><source>${java.version}</source><target>${java.version}</target><skip>true</skip><encoding>UTF-8</encoding><compilerArguments><extdirs>${project.basedir}/src/main/resources/lib</extdirs></compilerArguments></configuration></plugin><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-war-plugin</artifactId><version>3.1.0</version><configuration><webResources><resource><directory>src/main/resources/lib</directory><targetPath>WEB-INF/lib</targetPath><includes><include>**/*.jar</include></includes></resource><resource><directory>src/main/java/com/cetc52/screenshot/sdk</directory><targetPath>WEB-INF/sdk</targetPath></resource></webResources><failOnMissingWebXml>false</failOnMissingWebXml></configuration></plugin></plugins></build></project>

在POM文件中标签下的每个即表示该项目的一个直接依赖。

2 依赖的配置

 从上述的简单pom.xml文件中,可以看到Maven项目的依赖声明如下:

<project><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter</artifactId><type>…</type><scope>…</scope><optional>…</optional><exclusions><exclusion>…</ exclusion><exclusion>…</ exclusion></exclusions></dependency></dependencies>
</project>

根元素project下的dependencies可以包含一个或者多个dependency元素,以声明一个或多个项目依赖。

  1. groupId, artifactId, version具体含义同Maven坐标,对于任何一个依赖,使用Maven坐标机制找打准确的依赖。
  2. type依赖的类型,对英语项目坐标定义的packaging,大部分情况下,元素不必填写,默认为jar
  3. scop依赖范围
  4. optional标记依赖是否可选
  5. exclusions用来排除传递依赖

3 依赖的范围

Maven在编译项目、测试项目、以及运行项目时使用三套classpath。编译时classpath为src/main/resources,测试时classpath为src/test/resources,在运行时classpath则为target/classes。
依赖范围就是用来控制依赖与这三种classpath(编译classpath、测试classpath、运行classpath)的关系。

不考虑import依赖范围,其他各种依赖范围与三种classpath的关系参见Maven依赖范围与classpath、依赖传递如图:

4 传递性依赖

 Maven在帮助开发人员根据POM下载依赖时,会自动解析Maven项目的依赖,包括直接在POM文件中定义的直接依赖,以及每个依赖依赖的其他依赖。这个过程会自动进行,不需要手动干预。
spring-core有一个依赖commons-logging依赖。

<dependency><groupId>commons-logging</groupId><artifactId>commons-logging</artifactId><version>1.2</version>
</dependency>

 该依赖没有声明依赖范围,那么其依赖范围就是默认的compile。因此依赖图示如下:

 通过传递性依赖机制,Maven项目就不需要考虑它依赖了什么,也不用担心引入多余的依赖。Maven会解析各个直接的POM,将那些必要的间接依赖以传递性依赖的形式引入到当前项目中。

4.1 传递性依赖和依赖调解

 假设A依赖B,B依赖C,我们说A对于B是第一直接依赖,B对于C是第二直接依赖。A对于C是传递性依赖。第一直接依赖的范围和第二直接依赖的范围决定了传递性依赖的范围。下表中,最左边表示第一直接依赖范围,最上边为第二直接依赖范围,中间的交叉单元格则表示传递性依赖范围。

 通过查看上图,可以发现这样的规律,当第二直接依赖的范围为compile的时候,传递性依赖范围与第一直接依赖的范围一致。当第二直接依赖的范围为test的时候,依赖不会传递;当第二直接依赖的范围为是provided的时候,只传递第一直接依赖范围也为provided的依赖,且传递性依赖范围同样为provided;当第二直接依赖的范围是runtime的时候,传递性依赖的范围与第一直接依赖一致,但compile例外,此时传递性依赖的范围为runtime

5 依赖调解

 大部分情况下,我们只需要关心项目的直接依赖是什么,而不用考虑这些依赖会引入什么传递性依赖,当传递性依赖造成问题的时候,则需要清楚的知道该传递性依赖是从那条依赖路径引入的。

6 可选依赖

 一种场景是A–>B, B–>X(可选),B–>Y(可选),如果这三个依赖的范围都是compile,那么X、Y、就是A的compile范围传递性依赖。然而由于这里X、Y是可选依赖,依赖不会传递。换句话说X、Y不会对A有任何影响。
项目B实现了两个特性,其中一项特性依赖X,另一项特性依赖Y,而且两个特性是互斥的。


 上述图片中,使用表示依赖是可选的。它们zhi 对当前项目B产生影响,当其他项目需要依赖B的时候,这两个依赖不会传递,因此,当项目A依赖于项目B的时候,如果其实际使用MySQL数据库,那么在项目A中就必须显式的声明mysql-connector-java这个依赖。
 在理想的情况下,是不应该使用可选依赖的。使用可选依赖的原因是一个项目实现了多个特性,在面向对象设计中,存在单一职责原则,意为一个类应该只有一个原则,而不是糅合太多的功能,这个原则在规划Maven项目的时候同样适用。

7 总结

 本文章总结了Maven实战p62—p68的内容。主要内容包括Maven项目中依赖声明的格式,依赖范围的含义传递性依赖和依赖范围,以及依赖调解的两个原则。最后对于可选依赖的使用进行了简要的阐述,希望能够通过该文档增加对依赖理解的深度。

8 下载

Maven 依赖详细理解.pdf

                                                             2019年6月7日17:22:55端午第一天于马塍路36号

Maven依赖详细理解相关推荐

  1. Maven依赖配置和依赖范围

    文章目录 1.美图 2.参考 3.概述 4.依赖的配置 5.依赖的范围 5.1 compile 5.2 test 5.3 provided 5.4 runtime 5.5 system 5.6 imp ...

  2. maven依赖冲突解决_Maven依赖树–解决冲突

    maven依赖冲突解决 Maven Dependency Tree is very helpful in understanding the project dependencies and reso ...

  3. idea中创建maven依赖下的web工程(一)----用户登录界面

    如果你对idea中创建maven依赖下的web工程不是很了解,请参见上一篇博客--idea中创建maven依赖下的第一个web工程 各路大神对于idea的基本操作已经非常的熟悉了, 嗯,我还是一只入门 ...

  4. Maven依赖解析之倍增提速,eBay Velocity实践的开源新算法

    Maven 作为程序员所熟悉的构建工具,在eBay内部同样被广泛使用.maven-resolver 是Maven的核心组件.它将项目声明的所有依赖 (dependency) 予以解析,算得依赖图 (d ...

  5. Maven 依赖冲突那些事

    详细带你了解 Maven 依赖冲突的问题原因,以及解决办法.并教你生产碰到这类的问题实战技巧. 0x00. 前言 依赖冲突是日常开发中经常碰到的过程,如果运气好,并不会有什么问题.偏偏小黑哥有点背,碰 ...

  6. 碰到Maven依赖冲突,想砸电脑?这个IDEA插件必须了解一下...

    点击上方"方志朋",选择"设为星标" 回复"666"获取新整理的面试资料 来源:https://urlify.cn/mAj6Nj # 何为依 ...

  7. 漫画谈一下Maven依赖,百分之90的同学不知道!

    Maven 依赖排除(Exclusions) 因为 Maven 构建的项目具有依赖可传递的特性,当你在 pom.xml添加某个依赖时,可能也会引入不需要的依赖到你的项目中,这将会会可能引起如下问题: ...

  8. maven排除依赖包的子依赖_漫画谈一下Maven依赖

    Maven 依赖排除(Exclusions) 因为 Maven 构建的项目具有依赖可传递的特性,当你在 pom.xml添加某个依赖时,可能也会引入不需要的依赖到你的项目中,这将会会可能引起如下问题: ...

  9. maven插件依赖_当Maven依赖插件位于

    maven插件依赖 问题: 我们进行了一个集成测试,该测试创建了一个Spring ClassPathXmlApplicationContext ,同时这样做导致NoSuchMethodError爆炸. ...

最新文章

  1. python3.8.5怎么用-Python 3.8.5 正式发布
  2. Java 复制List的值
  3. BZOJ 3732 Network
  4. 教你10招最有效防电脑辐射方法
  5. CentOS内核编译
  6. 将SpringBoot应用Docker化并部署到SAP云平台
  7. 第一季2:视频设备开发的技术流
  8. 传智播客python2018_Python视频教程下载-2018传智播客Python视频教程下载-西西软件下载...
  9. DaVinci Resolve Studio 17.4.1 Mac(达芬奇调色软件)
  10. Could not resolve type alias ‘‘
  11. 解决mysql客户端中文显示乱码
  12. 计算所汉语词性标记集
  13. 数据库实验3 表、ER图、索引和视图的基础操作
  14. 锂电池充电——充电保护电路
  15. 【python】图片处理_分割图片
  16. 第七次作业(团队项目——Alpha阶段开发)(3)
  17. 无法验证驱动程序的签名_无法验证应用?掉签名打不开应用?没越狱也能解决!...
  18. 物联网阿里云——Android Mqtt协议连接阿里云
  19. .Net发布到IIS服务器,IIS服务器配置
  20. mysql服务怎么启动和关闭?

热门文章

  1. C语言--确定到底谁是凶手
  2. ssm毕设项目康健医药公司进销存管理22jao(java+VUE+Mybatis+Maven+Mysql+sprnig)
  3. FX3U基本指令学习
  4. or计算遇到存在零“0”的情况
  5. 音视频基础+ffmpeg原理(视频基础知识)
  6. 4.实操(Credit Card Fraud Detection)
  7. 手把手教你建立微信公众平台
  8. 2017年蓝桥杯A组 跳蟋蟀 (BFS)
  9. ibm服务器 产品型号对应表,产品线最全 IBM中小企业服务器选型指南
  10. C语言查找素数的几种实现方法及代码的优化