博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
4,maven坐标和依赖
阅读量:6964 次
发布时间:2019-06-27

本文共 3161 字,大约阅读时间需要 10 分钟。

hot3.png

一. 何为maven坐标

      Maven 定义了这样一组规则:世界上任何一个构件都可以使用 Maven 坐标唯一标识, Maven 坐标的元素包括 groupId artifactId  version  packaging  classifier 

    Maven 内置了一个中央仓库的地址(  ),该中央仓库包含了世界上大部分流行的开源项目构件, Maven 会在需要的时候去那里下载。

二. 坐标详解

      groupId 定义了当前 Maven 项目隶属的实际项目。一个实际项目往往会被划分成很多模块,一个模块可能就是一个Maven 项目。 goupId 不应该对应项目隶属的组织或公司,因为一个组织或公司可能会有多个实际项目。 groupId 的表示方式与 Java 包名类似。

      artifactId 定义实际项目中的一个 Maven 项目(模块)。推荐使用实际项目名作为 artifactId 的前缀,如: nexus-indexer 。因为默认情况下 Maven 生成的构件会以 artifactId 开头,用实际项目名作为前缀就能方便从一个 lib 文件夹中找到某个实际项目的一组构件。

      version 定义了当时 Maven 项目所处的版本。

      packaging 定义了 Maven 项目的打包方式,通常与所生成构件的文件扩展名对应。不同的打包方式会影响构建的生命周期。比如 jar 打包与 war 打包会使用不同的命令。不定义 packaging 的时候,默认为 jar 。( package  "maven-plugin" 的构件扩展名是 jar 

      classifier 定义构建输出的一些附属构件。附属构件与主构件对应。如 Java 项目的 javadoc  sources  TestNG 项目默认是基于 Java 1.4 平台的,而它又提供了一个 jdk5 的附属构件。我们不能直接定义项目的 classifier ,因为附属构件不是项目直接默认生成的,而是由附加的插件帮助生成的。

      groupId  artifactId  version 是必须定义的, packaging 是可选的, classifier 是不能直接定义的。

    项目构件的文件名与坐标相对应,一般为: artifactId-version[-classifier].packaging

三. 依赖的配置

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

      groupId  artifactId  version 是依赖的基本坐标。

    type 为依赖的类型,对应于项目坐标定义的 packaging 

    scope是依赖的范围。 

      optional 标记依赖是否是可选的。 

      exclusions 用来排除传递性依赖。

四. 依赖范围

    依赖范围包含:

        compile :编译依赖范围。对于编译、测试、运行三种 classpath 都有效。是默认的依赖范围。

        test :测试依赖范围。只对测试 classpath 有效。如 Junit

        provided :已提供依赖范围。只对编译、测试 classpath 有效。如 servlet-api ,运行时容器已提供。

        runtime :运行依赖范围。只对测试和运行 classpath 有效。如 JDBC 驱动实现,编译主代码时只需要 JDK 提供的JDBC 接口。

        system :系统依赖范围。与 Provided 依赖范围一致。但依赖是通过 systemPath 元素显式指定文件的路径,与本机系统绑定,一般无法移植。

        import :导入依赖范围。不会对 3  classpath 产生实际影响。

五. 传递性依赖

      Maven 会解析各个直接依赖的 POM, 将那些必要的间接依赖,以传递性依赖的形式引入到当前的项目中。假设 A 依赖 B  B 依赖 C ,我们称 A  B 是第一直接依赖, B  C 是第二直接依赖, A  C 是传递依赖。

六. 依赖调解

    依赖调解第一原则:路径最近者优先

        如:依赖关系为:A->B->C->X(1.0) A->D->X(2.0)  

        结果是X(2.0)会被解析使用。

    依赖调解第二原则:最先声明者优先。

        如:A->B->X(1.0)A->D->X(2.0)  B  D 先声明

        结果是 X(1.0)会被解析使用。

七. 可选依赖

    如果项目 B 实现了两个特性,特性一依赖于项目 X ,特性二依赖于项目 Y ,而 X  Y 是互斥的。(比如 B 是一个持久层隔离包,支持多种数据库, X  MySQL 驱动, Y  PostgreSQL 驱动。)那么 X  Y  B 的可选依赖。如果 A依赖 B ,则 A 不再传递依赖 X  Y 而需要显式地声明 X  Y 为其直接依赖。

    在理想情况下,是不应该使用可选依赖的。因为在面向对象设计中,有个单一职责性原则,意指一个类应该只有一项职责,而不是糅合太多的功能。这个原则在规划maven项目的使用同样适用。在上段文字的说明中,更好的做法是为MysqlPostgreSQL 分别创建一个maven项目

八. 最佳实践

1. 排除依赖

    有时候希望排除某些传递依赖(比如传递依赖因版权限制不可用或者传递依赖是个 SNAPSHOT 版本)而显示地声明他们的替代者。可以在 <exclusion> 中声明相排除的传递依赖,而多增加一个 <dependency> 声明它的替代者。<exclusion> 只用声明 groupId  artifactId 就行。

2. 归类依赖

    对于来自同一个实际项目的多个项目依赖,他们版本应该是一致的,这样,可以先用 <properties> 定义一个版本号变量。如:

        <properties><spring.version>2.5.6</spring.version></properties> 

    然后在版本信息的位置使用 ${spring.version} 来引用它。

3. 优化依赖

    可以执行 mvn dependency:list  mvn dependency:tree 查看已解析的依赖( resolved dependency )

    可以执行 mvn dependency:analyze 来分析项目中的直接用到但未显示声明的依赖( Used undeclared dependencies )和声明了但未用到的依赖( Unused declared dependencies )。 Used undeclared dependencies是项目直接用到了,但通过传递依赖引入的项目,这样当项目的直接依赖更新时,传递依赖也会随之更新,从而会导致项目代码与传递依赖不兼容。 Unused declared dependencies 并不是完全没用的依赖,只是在编译主代码和测试代码时没用,但可能会在执行测试和运行时用到。

转载于:https://my.oschina.net/hongdengyan/blog/150596

你可能感兴趣的文章
解决字符替换时大小写的敏感问题
查看>>
linux 磁盘管理上(分区操作,格式化文件,挂载和卸载)
查看>>
我的友情链接
查看>>
以太网为什么要有最小帧长?
查看>>
IBM服务器BMC 远程管理
查看>>
Altium Designer 常用快捷键(记录)
查看>>
BIO模型分析
查看>>
linux 修改默认编码
查看>>
用磁带后改用本地磁盘备份可能出现的问题
查看>>
Python装饰器进阶
查看>>
调用 SetRect 函数可以设定矩形区域
查看>>
zabbix监控之nginx
查看>>
MaxCompute Studio 使用入门
查看>>
读《Linux Shell脚本攻略》第1章笔记
查看>>
某电商项目PostgreSQL数据库备份恢复方案
查看>>
UI2Code智能生成Flutter代码——机器生成代码
查看>>
Node.js 应用故障排查手册 —— 类死循环导致进程阻塞
查看>>
Discord 公司如何使用 Cassandra 存储上亿条线上数据
查看>>
mysql8.0 二进制安装
查看>>
内存问题导致机器无法正常开机
查看>>