<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 |