Maven坐标和依赖
1、坐标
mvn坐标为各种构件引入了秩序,任何一个构件都必须明确定义自己的坐标,而一组mvn坐标是通过一些元素定义的,它们是groupId、artifactId、version、packaging、classifier
groupId:定义当前mvn项目隶属的实际项目,如spring
artifactId:定义实际项目中的一个mvn项目(模块),推荐使用实际项目名称作为artifactId的前缀,如spring-core
version:定义mvn项目当前所处的版本
packing:定义mvn项目的打包方式,默认为jar。packaging并非一定与构件扩展名对应,如packaging为maven-plugin的构件扩展为jar。
classifier:用来帮助定义构件输出的一些附属构件。如主构件nexus-indexer-2.0.0.jar,可以通过一些插件生成nexus-indexer-2.0.0-javadoc.jar、nexus-indexer-2.0.0-sources.jar。注意:不能直接定义项目的classifier,因为附属构件不是项目直接默认生成的,而是由附加的插件帮助生成的。
2、依赖
2.1、依赖的配置
在mvn项目的pom.xml中,根元素project下的dependencies元素包含一个或多个dependency元素,用于声明一个或多个项目依赖,dependency包含的子元素如下:
groupId、artifactId、version:mvn根据坐标找到需要的依赖
type:依赖的类型,对应坐标中的packaging,默认为jar
scope:依赖的范围
optional:标记依赖是否可选
exclusions:用来排除传递性依赖
2.2、依赖的范围
依赖的范围用来控制依赖与三种classpath(编译classpath、测试classpath、运行classpath)的关系,mvn有以下几种依赖范围:
compile:编译依赖范围。默认使用该依赖范围,使用此依赖范围的mvn依赖,对于编译、测试、运行三种classpath都有效。
test:测试依赖范围。对测试classpath有效,对编译、运行classpath无效
provided:已提供依赖范围。对编译和测试classpath有效,但在运行时无效。如servlet-api.jar,由于容器已经提供,运行时就不需要重复引入。
runtime:运行时依赖范围。对测试和运行classpath有效,但在编译时无效。如JDBC驱动,项目主代码的编译只需要JDK提供的JDBC接口,只有在执行测试或者运行项目的时候才需要实现接口的具体JDBC驱动。
system:系统依赖范围。和provided依赖范围一致,但是使用system范围的依赖时必须通过systemPath元素显式指定依赖文件的路径。此类依赖不是通过mvn仓库解析的,与本机系统绑定可能造成构件的不可移植,应谨慎使用。systemPath元素可以引用环境变量,如<systemPath>${java.home}/lib/rt.jar</systemPath>
import:导入依赖范围
2.3、传递性依赖
依赖范围不仅可以控制依赖与三种classpath的关系,还对传递性依赖产生影响。假设A依赖于B,B依赖于C,那么A对于B是第一直接依赖,B对于C是第二直接依赖,A对于C是传递性依赖。第一直接依赖的范围和第二直接依赖的范围决定了传递性依赖的范围。下面表格展示了依赖范围影响传递性依赖的结果信息表,第一列表示第一直接依赖,第一行表示第二直接依赖:
compile | test | provided | runtime | |
compile | compile | - | - | runtime |
test | test | - | - | test |
provided | provided | - | provided | provided |
runtime | runtime | - | - | runtime |
规律:
1、当第二直接依赖的范围是compile,传递性依赖的范围与第一直接依赖的范围一致;
2、当第二直接依赖的范围是test,依赖不会发生传递;
3、当第二直接依赖的范围是provided,只传递第一直接依赖范围也为provided的依赖,且传递性依赖的范围同样为provided;
4、当第二直接依赖的范围是runtime,传递性依赖的范围与第一直接依赖的范围一致,但compile例外,此时传递性依赖的范围为runtime。