Maven - 依赖
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.x</groupId> <artifactId>helloworld</artifactId> <packaging>war</packaging> <version>0.0.1-SNAPSHOT</version> <name>helloworld Maven Webapp</name> <properties> <spring>3.0.5.RELEASE</spring> </properties> <dependencies> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>3.8.1</version> <scope>test</scope> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-core</artifactId> <version>${spring}</version> </dependency> </dependencies> </project>
dependencies节点可以包含一个或多个dependency元素,以声明一个或多个项目依赖。
每个依赖可以包含的元素有:
groupId,artifactId和version:依赖的基本坐标,对于任何一个依赖来说,基本坐标是最重要的,maven根据坐标才能找到需要的依赖。
type:依赖的类型,对于项目坐标定义的packaging,默认值为jar。
scope:依赖范围。
optional:标记依赖是否可选。
exclusions:用来排除传递性依赖
------------------------------------------------------------------------------------------------------------------------
*scope依赖范围
maven在编译项目主代码的时候需要使用一套classpath。假如,在编译项目主代码的时候需要用到spring-core,该文件以依赖的方式被引入到classpath中。其次,maven在编译和执行测试代码的时候会使用另外一套classpath。如:JUnit就是一个很好的例子,该文件也以依赖的方式引入到测试使用的classpath中,不同的是这里的依赖范围是test。最后,实际运行maven项目的时候,又会使用一套classpath。
依赖范围就是用来控制依赖与这三种classpath(编译classpath,测试classpath,运行classpath)的关系,maven有以下几种依赖范围:
1.compile :编译依赖范围。如果没有指定,就会默认使用该依赖范围。使用此依赖范围的maven依赖,对于编译、测试、运行三种classpath都有效。典型的例子如项目依赖spring。
2.test :测试依赖范围。使用此依赖范围的maven依赖,只对于测试classpath有效,在编译主代码或者运行项目时将无法使用此类依赖。典型的例子是:JUnit,它只有在编译测试代码及运行测试的时候才需要。
3.provided : 已提供依赖范围。使用此依赖范围的maven依赖,对于编译和测试classpath有效,但在运行时无效。典型的例子是:servlet-api,编译和测试项目的时候需要该依赖,但在运行项目的时候,由于容器已经提供,就不需要maven重复地引入一遍。
4.runtime:运行时依赖范围。使用此依赖范围的maven依赖,对于测试和运行classpath有效,但在编译主代码时无效。典型的例子是JDBC驱动实现,项目主代码的编译只需要JDK提供的JDBC接口,只有在执行测试或者运行项目的时候才需要实现上述接口的具体JDBC驱动。
5.system: 系统依赖范围。该依赖与三种classpath的关系,和provided依赖范围完全一致。但是,使用system范围的依赖时必须通过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>
6.import:导入依赖范围。在依赖dependencyManagement下使用,作用是将目标的pom中dependencyManagement导入合并到当前pom的dependencyManagement元素中。
依赖范围与classpath的关系
依赖范围(scope) |
编译classpath有效 |
测试classpath有效 |
运行classpath有效 |
例 子 |
---|---|---|---|---|
compile |
Y |
Y |
Y |
spring jar |
test |
---- |
Y |
---- |
junit jar |
provided |
Y |
Y |
---- |
jsp-api |
runtime |
---- |
Y |
Y |
jdbc驱动实现 |
system |
Y |
Y |
---- |
本地,maven仓库之外的类文件 |
*传递性依赖
如:有A项目中,依赖spring [B], 而spring又依赖commons-logging [C]. C就是A的一个传递性依赖。
A ----> B依赖范围:compile 第一直接依赖 ,
B----> C依赖范围:compile 第二直接依赖,
A----> C 传递性依赖范围是:compile.
依赖范围影响传递性依赖
最左边一列表示第一直接依赖范围, 最上面一行表示第二直接依赖范围, 中间交叉单元格则表示传递性依赖范围:
compile |
test |
provided |
runtime |
|
---|---|---|---|---|
compile |
compile |
---- |
---- |
runtime |
test |
test |
---- |
---- |
test |
provided |
provided |
---- |
provided |
provided |
runtime |
runtime |
---- |
runtime |