• Maven实战读书笔记(三):Maven依赖


    3.1 依赖的配置

    一个依赖声明可以包含下面元素:

    <dependencies>
    	<dependency>
    		<groupId></groupId>
    		<artifactId></artifactId>
    		<version></version>
    		<type></type>
    		<scope></scope>
    		<optional></optional>
    		<exclusions>
    			<exclusion>
    			</exclusion>
    		</exclusions>
    	</dependency>
    </dependencies>
    

    groupId、artifactId、version依赖的基本坐标。
    type:依赖的类型,对应于项目坐标定义的packaging,默认:jar
    scope:依赖的范围。
    optional:标志依赖是否可选,true/false
    exclusions:用来排除传递性依赖。

    3.2 依赖范围

    依赖范围是用来控制依赖于三种classpath(编译classpath、测试classpath、运行classpath)的关系。
    Maven的依赖范围有如下几种:
    compile:编译依赖范围,默认值,对三种classpath都有效。
    test:测试依赖范围,只对测试classpath有效,典型例子如:Junit
    provided:已提供依赖范围,对编译和测试classpath有效,但在运行时无效,典型例子如:servlet-api,运行时由容器提供。
    runtime:运行时依赖范围,对测试和运行classpath有效,编译主代码时无效,典型例子如:JDBC驱动实现,编译时只需要JDK提供的JDBC接口,运行才需要具体的实现。
    system:系统依赖范围,对编译和测试classpath有效,但在运行时无效。使用该范围时,必须通过systemPath元素指定依赖的路径。

    	<dependency>
    		<groupId>javax.sql</groupId>
    		<artifactId>jdbc-stdext</artifactId>
    		<version>2.0</version>
    		<scope>system</scope>
    		<systemPath>${java.home}/lib/rt.jar</systemPath>
    	</dependency>
    

    import:导入依赖范围,该范围不会对三种classpath产生实际应用,会将目标POM中的dependencyManagement配置导入合并到当前POMdependencyManagement元素中。
    依赖范围

    3.3 传递性依赖和依赖范围

    Maven的传递性依赖是指不需要考虑你依赖的库文件所需要依赖的库文件,能够将依赖模块的依赖自动的引入。

    依赖的范围不仅可以控制依赖与三种classpath的关系,还会对传递性依赖产生影响。假设A依赖于B,B依赖于C,则说A对于B是第一直接依赖,B对C是第二直接依赖,A对于C是传递依赖。第一直接依赖范围和第二直接依赖范围决定了传递性依赖的范围,其结果如下:
    传递性依赖

      第二直接依赖范围是`compile`时,传递性依赖范围与第一直接依赖范围一致;
      第二直接依赖范围是`test`时,依赖不会得以传递;
      第二直接依赖范围是`provided`时,只传递第一直接依赖范围也为provided的;
      第二直接依赖范围是`runtime`时,传递性依赖的范围与第一直接依赖范围一致,`compile`例如,此时的传递性依赖范围为`runtime`。
    

    3.4 依赖调解

    一般情况下,只关心项目的直接依赖,而不关心直接依赖引入的传递性依赖,但当传递性依赖出现问题时,需要知道该传递性依赖是怎么引进来的。
    Maven依赖调解第一原则:路径最近者优先,如:A->B->C->X(1.0)、A->D-X(2.0),则X的2.0版本会被解析使用;
    Maven依赖调解第二原则:第一声明者优先,如:A->B->X(1.0)、A->D->X(2.0),若B的依赖声明在D之前,则使用X的1.0版本,否则使用X的2.0版本。

    3.5 可选依赖

    假设有下面的依赖关系:A->B、B->X(可选)、B->Y(可选),由于X和Y是可选的,所以依赖不会传递,X和Y不会对A有任何影响。

    可选依赖的必要性:项目B实现2种特性,特性一依赖于X,特性二依赖于Y,而且这两个特性是互斥的,用户不可能同时适用这两个特性,这时候可选依赖就有用了。
    原则上说,是不应该使用可选依赖的,根据面向对象的单一职责性原则,该原则同样适用于Maven项目的规划。

    3.6 最佳实践

    1)排除依赖

    传递性依赖会给项目隐式的引入很多依赖,这极大的简化了项目依赖的管理,但是有时某些依赖会带来问题,这时需要把带来问题的依赖排除掉。

    2)归类依赖
    来自同一个项目的不同模块,其版本号应该是相同的,如springframework项目有spring-corespring-beans模块,对这些模块的版本号通过属性定义,再进行引用,这样可以进行版本的整体升级:

    	<properties>
    		<springframework.version>4.3.13.RELEASE</springframework.version>
    	</properties>
    	<dependency>
    		<groupId>org.springframework</groupId>
    		<artifactId>spring-core</artifactId>
    		<version>${springframework.version}</version>
    	</dependency>
    	<dependency>
    		<groupId>org.springframework</groupId>
    		<artifactId>spring-beans</artifactId>
    		<version>${springframework.version}</version>
    	</dependency>
    

    3)优化依赖

    去掉多余的依赖,显示声明某些必要的依赖。
    通过mvn dependency:list 查看项目已解析的依赖
    通过mvn dependency:tree 查看项目的依赖树

  • 相关阅读:
    JAVA 基础 / 第二十三课: 类和对象 / 什么是JAVA中的方法重载? 构造方法?
    JAVA 基础 / 第二十二课: 类和对象 / 什么是JAVA中的引用? 继承 ?
    【Oracle】ORA-12518, TNS:listener could not hand off client connection
    Oracle 将当前系统时间戳插入timestamp字段 无效的月份
    Git本地有未提交文件,直接拉取远端最新版本
    Windows下分布式环境搭建以及简单测试
    Python——pip快速下载第三方库到指定环境
    Python——Scrapy爬取链家网站所有房源信息
    Python——XPath提取某个标签下所有文本
    Python——全国瓜子二手车数据分析
  • 原文地址:https://www.cnblogs.com/Jxwz/p/8372372.html
Copyright © 2020-2023  润新知