maven坐标和依赖

原创
2018/08/17 02:44
阅读数 109

一、maven坐标详解

	<groupId>com.fgt.club</groupId>
	<artifactId>club-common-service-facade</artifactId>
	<version>3.0.0</version>
	<packaging>jar</packaging>

maven的坐标元素说明:

groupId: 依赖的基本坐标之一,用于标识当前maven项目所隶属的实际项目;

artifactId:依赖的基本坐标之一,用于标识groupId定义的实际项目中的一个项目(或模块),一般使用实际项目名作为前缀;

version:依赖的基本坐标之一,用于标识maven项目的版本;

packaging:该元素定义了maven项目的打包方式,打包方式与生成文件的文件扩展名通常是一致的,但并不是绝对。

二、maven依赖的配置

maven的项目依赖是在dependency元素中声明的,我们通过一个例子分析下dependency的组成元素。

		<dependency>
			<groupId>...</groupId>
			<artifactId>...</artifactId>
             <version></version>
             <type>...</type>
             <scope>...</scope>
             <optional>...</optional>
             <exclutions>
               <exclution>
                ...
               </exclution>
               ......
             </exclutions>
		</dependency>

1 - dependency元素的说明:

groupId: 依赖的基本坐标之一,用于标识当前maven项目所隶属的实际项目;

artifactId:依赖的基本坐标之一,用于标识groupId定义的实际项目中的一个项目(或模块),一般使用实际项目名作为前缀;

version:依赖的基本坐标之一,用于标识maven项目的版本;

scope:依赖的范围,用于定义当前maven依赖的在项目中的使用范围,默认为compile(在编译、测试、运行时使用);

optional:标记依赖是否可选,默认为false;

exclutions:用于排除传递性性依赖,子元素节点<exclution>包含dependency元素只是不含版本信息<version>;

2 - 依赖范围

maven在编译、测试、运行项目的时候使用的是不同套的classpath,而依赖范围是用于控制maven依赖与这3种classpath(分别是编译classpath、测试classpath和运行时classpath)的关系,maven中依赖范围时是在dependency的scope元素中定义的以下时不同依赖范围的说明:

compile:编译依赖范围。如果dependency的scope未指定默认使用该依赖范围,使用此依赖范围对编译、测试、运行classpath都有效;

test:测试依赖范围,使用此依赖范围只对测试classpath有效,对于编译和运行classpath均无效,常见的有JUnit单元框架,只在编译测试代码和测试的时候有效;

provided:已提供依赖范围。使用此依赖范围的maven依赖对于编译和测试classpath有效,而对于运行时classpath无效。典型的例子时servlet-api在编译和测试时需要但是运行时由于容器例如tomcat中已经提供因此不需要重复引用;

runtime:运行时依赖。使用此依赖范围的maven依赖对于测试和运行classpath有效但是在编译代码的时候无效,典型例子是jdbc驱动,项目主代码主需要JDK提供的通用JDBC接口与只在运行和测试时才需要实现通用接口的具体JDBC驱动实现;

system:系统范围依赖。该依赖与provided依赖范围一致,不同的地方在于,system范围依赖必须在dependency中额外指定<systemPath>元素显示指定依赖文件的路径;

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

 

3 - 传递性依赖

maven的传递性依赖是指如果在一个maven项目中项目pom文件定义的直接依赖项目A也依赖了另一个项目B那么该项目也间接依赖B,maven会解析项目pom文件中定义的各个直接依赖的pom将所有必要的间接依赖以传递性依赖的方式导入当前项目。依赖范围不仅可以控制依赖与三种classpath的关系而且会对传递性依赖产生影响。例如项目account直接依赖于spring-core,依赖范围是默认compile而spring-core又依赖于common-logging依赖范围也是compile,所以account对于common-logging的依赖范围也是compile,其中account对于spring-core被我们称为第一直接依赖,而spring-core对于common-logging的依赖则被我们称为第二直接依赖以下是依赖范围影响传递性依赖范围的表格,第一列为第一直接依赖,而第一行为第二直接依赖。

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

 

4 - 依赖调解

maven引入的传递性依赖机制虽然大大简化和方便了依赖声明大部分情况我们不需要关心项目的传递性依赖是什么,但是当传递性依赖出现问题的时候我们要学会解决它。首先我们要了解maven依赖调解遵循的两条原则:

1)最短路径原则。如果在项目A中存在这样的一条依赖链A->B->C->M(1.0),A-B->M(2.0)那么最终哪个2.0版本的依赖M会被项目A解析使用,因为A->B-M(2.0)的路径长度更短;

2)最先声明原则。当依赖路径长度相同的时候,谁现在POM文件中申明解析使用谁(这里声明的依赖指的是冲突依赖本身或者依赖于它的maven依赖)

常用于依赖调解分析的maven命令:maven dependency:tree

5 - 可选依赖

在maven项目中被声明为可选依赖的依赖不会被传递。假如存在项目A依赖于B,项目B依赖于X和Y,但是X和Y在B中dependency的optional声明中被设置为可选依赖true,那么X,Y依赖不会传递到A,X,Y不会对项目A有任何影响。maven这种特性的使用情况一般是在maven项目需要实现多种特性,且每种特性依赖一套相互互斥的maven依赖,例如一个maven项目实现了于多种数据库的连接操作,不同数据库依赖的数据库驱动均不同因此打包时POM文件的各种数据库驱动的dependency的optional元素必须设置为true,当我们在项目中需要使用某种数据库的时候在引入该项目的基础上再引入对应的数据库驱动就不会有冲突。

 

展开阅读全文
加载中
点击引领话题📣 发布并加入讨论🔥
打赏
0 评论
0 收藏
0
分享
返回顶部
顶部