Maven专题1——坐标与依赖

坐标

坐标用来唯一定位一个Maven构件:

  • GAV(必需):groupId, artifactId, version
  • packaging(可选): 可取值如:jar(缺省), war, pom, maven-plugin等,其中父项目的packaging通常是pom,只用来声明项目元数据,用到的依赖、插件,以及项目中的子模块等。
  • classifier: 不能直接定义,通常用来辅助定义附属构件,如:javadoc、sources构件等。

依赖

在POM的<dependency>元素中,有以下元素可以用来配置依赖:

  • GAV:groupId、artifactId、version。
  • type:对应于被依赖模块的packaging元素的值。
  • scope:

compile:默认依赖范围,对编译、测试、运行三种classpath都有效,用于编译、测试、运行阶段都需要用到的依赖;
test:只对测试classpath有效,编译主代码、运行项目时无法使用的依赖。
provided:对编译、测试有效,在运行时无效。
runtime:运行时依赖,对测试、运行classpath有效,在编译主代码时无效;
import:不会对编译、测试、运行的classpath产生实际影响,
system:需通过systemPath显式指定依赖的路径,不通过Maven仓库解析,会造成构建的不可移植,不推荐使用。

  • optional:标记依赖是否可选;
  • exclusions:排除某些传递依赖。

管理typepom类型的依赖

通常一个项目的pom类型的构件用来声明使用到的依赖,为了沿用和管理其声明的所有依赖,通常可以在dependencyManagement元素中如下引用:

<dependencyManagement>
    <dependencies>
        <dependency>
            <artifactId>org.springframework.boot</artifactId>
            <groupId>spring-boot-dependencies</groupId>
            <version>${spring.boot.version}</version>
            <scope>import</scope>
            <type>pom</type>
        </dependency>
    </dependencies>
</dependencyManagement>

以此来保持我们项目使用的依赖和Spring Boot声明的一致。

依赖范围与classpath关系

依赖范围 对编译classpath有效 对测试classpath有效 对运行时classpath有效 示例
compile Y Y Y spring-core
provided Y Y - servlet-api
runtime - Y Y JDBC驱动
test - Y - JUnit
system Y Y - 本地Maven仓库以外的类库文件

依赖范围与依赖传递的关系

- compile test provided runtime
compile compile - - runtime
test test - - test
provided provided - provided provided
runtime runtime - - runtime

表格说明:

  1. 最左侧列是第一直接依赖,如A依赖于B,B依赖于C时,A对于B即是第1直接依赖;
  2. 最上侧行是第2直接依赖,如A依赖于B,B依赖于C时,B对于C即是第2直接依赖;
  3. 表中其他单元格表示传递依赖的依赖范围,即A传递依赖C的范围。

结论:

  1. 第2直接依赖的范围是compile时,传递依赖的范围与第1直接依赖一致;
  2. 第2直接依赖是test时,依赖不会传递;
  3. 第2直接依赖是provided时,只传递依赖第1直接依赖也是provided范围的依赖。

依赖调解

  1. 路径最近者优先,例如:A->B->c->x(1.0),a->d->x(2.0),由于a通过第二条路径依赖x的距离更短,因此实际解析使用的是2.0的x。
  2. 最先声明者优先,例如:a->b->y(1.0),a->c->y(2.0),在依赖路径等长时,声明依赖b在声明c之前,则实际解析使用的是y(1.0)。

可选依赖

optional元素是true的依赖是可选依赖。

可选依赖通常用来阻断依赖传递,例如a->b,b->x(可选)、b->y(可选)。

这种情况通常出现在b有多种实现,一种可以使用x,另一种可以使用y的场景。

此时考虑非可选的场景,如果上述3个依赖范围都是compile,那么x和y也应该是a的compile依赖。

然而在可选依赖的场景下,依赖传递被打破,x和y只会对声明可选依赖于他们的b有影响,a并不会传递依赖x和y。

当声明a依赖于b时,就要指明a选择使用b依赖的x还是y,即需要在a中显式的声明依赖x或y。

对于存在可选依赖的场景,应考虑针对每一种可选依赖建立一个独立的模块对外提供功能,从而不使用可选依赖这个概念。

优化依赖

使用列表的形式查看依赖:

mvn dependency:list

使用树形结构查看依赖树:

mvn dependency:tree

分析依赖状况:

mvn dependency:analyze

analyze会列出两类重点关注的依赖:

  1. 使用但未声明的依赖:指项目中使用到,但是是通过传递依赖传递进来的。
  2. 声明但未使用的依赖:项目中声明了但未使用的依赖,该命令只列出编译主代码、测试代码需要的依赖,并不会发现执行测试和运行时需要的依赖,所以不应该简单地删除声明了但未使用的依赖。

原文地址:https://www.cnblogs.com/zyon/p/11294226.html

时间: 2024-10-14 00:30:48

Maven专题1——坐标与依赖的相关文章

项目构建之maven篇:4.坐标与依赖及spring依赖注入demo

源代码下载 坐标 <groupId>com.demo.animal</groupId> <artifactId>animal-core</artifactId> <version>0.0.1-SNAPSHOT</version> <packaging>jar</packaging> groupId:定义当前maven项目隶属的实际项目 artifactId:定义实际项目中的一个maven项目(模块),推荐实际项

Maven(2)-坐标和依赖

本文简要介绍Maven里面的坐标(coodinate)以及maven依赖管理(Dependency) 一.坐标 先来个截图: 在上图peoject栏目有groupId,artifactId,version,这个就是maven中坐标的概念,这三个属性能够唯一定位一个java架包,其中: groupId代表架包所在的组织(package的概念),比如com.cnblogs artifactId是一个单独架包(项目)的唯一表示 version代表当前项目的版本号 另外坐标还有个packaging属性,

Maven学习笔记之——坐标和依赖(上)

Maven学习笔记之--坐标和依赖(上) 1.    Maven坐标概念 Maven通过构件的坐标来在Maven仓库中定位到具体的构件.Maven的坐标元素包括groupId.artifactId.versiion.packaging.classifier.Maven内置了一个中央仓库地址.需要时Maven会根据坐标到其中下载.具体关于中央仓库的介绍在后面. 2.    Maven坐标详解 比如下面一组坐标: <groupId>org.andy.items</groupId> &l

maven详解之坐标与依赖

看着简单而又复杂的pom.xml文件,看似熟悉,当自己编写的时候觉得简单,但是看人家项目的时候又觉得复杂的很,现在我们一起来分析这个pom文件. Maven的坐标为各种构件引入了秩序,任何一个构件都必须明确的定义自己的坐标,maven的坐标包括如下的元素: groupId: 定义当前Maven项目隶属的实际项目 artifactId: 该元素定义实际项目中的一个Maven项目或模块 version: 该元素定义Maven项目当前所处的版本 packaging: 该元素定义Maven项目的打包方式

Maven 系列 三 :坐标和依赖

1 . 坐标 maven 的所有构件均通过坐标进行组织和管理.maven 的坐标通过 5 个元素进行定义,其中 groupId.artifactId.version 是必须的,packaging 是可选的(默认为jar),classifier 是不能直接定义的. groupId:定义当前 Maven 项目所属的实际项目,跟 Java 包名类似,通常与域名反向一一对应. artifactId:定义当前 Maven 项目的一个模块,默认情况下,Maven 生成的构件,其文件名会以 artifactI

Maven学习笔记之——坐标和依赖(中)

Maven学习笔记之--坐标和依赖(中) 1.    传递性依赖 1.1    何为传递性依赖 项目中经常有引入一个jar包还要引入其他与其相关的jar包.自己搜的话要注意很多.比如版本问题等.而Maven会解析解析各个直接依赖的POM.将哪些必要的间接依赖以传递依赖的形式引入到项目中. 依赖范围不仅可以控制依赖与三种classpath关系.还对传递依赖产生影响. 假设A依赖B,B依赖C,我们说A对于B是第一直接依赖,B对于C是第二直接依赖,A对于C是传递性依赖.第一直接依赖的范围和第二直接依赖

Maven学习笔记之——坐标和依赖(下)

Maven学习笔记之--坐标和依赖(下) 1.    最佳实践 归纳Maven依赖使用的常用技巧.方便用来避免和处理很多常见问题. 1.1.     排除依赖 传递性依赖会给项目隐式地引入很多依赖,这极大地简化了项目依赖的管理.但是有些时候这种特性也会带来问题.例如,当前项目有一个第三方依赖,而这个第三方依赖由于某些原因依赖了另外一个类库的SNAPSHOT版本,那么这个SNAPSHOT就会成为当前项目的传递性依赖,而SNAPSHOT的不稳定性会直接影响到当前的项目.这时候需要排除掉该SNAPSH

Maven学习笔记(四):坐标与依赖

Maven坐标详解: Maven定义了这样一组规则:世界上任何一个构件都可以使用Maven坐标唯一标识,Maven坐标的元素包括groupId.artifactId.version.packaging.classifier.我们只需要提供正确的坐标元素,Maven就能找到对应的构件.比如当需要使用Java5平台上的TestNG的5.8版本时,就告诉Maven:"groupId=org.testng; artifactId=testng; version=5.8; classifer=jdk15,

maven第5章坐标和依赖

5.5依赖范围 runtime:运行时依赖范围 举的例子是JDBC驱动实现,不理解? 5.6传递性依赖 5.7依赖调解 maven第5章坐标和依赖