目录
1、依赖范围Scope
在POM 4中,<dependency>中还引入了<scope>,它主要管理依赖的部署。目前<scope>可以使用5个值:
- compile:编译依赖范围,缺省值,对于编译、测试、运行三种classpath 都有效,适用于所有阶段,会随着项目一起发布;
- test:测试依赖范围,只对于测试classpath有效,在编译主代码或运行时无法使用此依赖;
- provided:已提供依赖范围。对于编译和测试classpath有效,运行时无时;典型例子如servlet-api;
- runtime:运行时依赖范围;对测试和运行classpath有效,编译主代码时无效;如JDBC驱动,适用运行和测试阶段。
- system:系统依赖范围;该依赖与三种classpath关系,和provided一样,需要显式提供包含依赖的jar,Maven不会在Repository中查找它。
依赖范围 (Scope) | 对于编译 classpath有效 | 对于测试 classpath有效 | 对于运行时 classpath有效 | 例子 |
---|---|---|---|---|
compile | Y | Y | Y | spring-core |
test | --- | Y | --- | Junit |
provided | Y | Y | --- | servlet-api |
runtime | --- | Y | Y | JDBC |
system | Y | Y | --- | servlet-api |
2、传递性依赖和依赖范围
compile | test | provided | runtime | |
---|---|---|---|---|
compile | compile | --- | --- | runtime |
test | test | --- | --- | test |
provided | provided | --- | provided | provided |
runtime | runtime | --- | --- | runtime |
3、依赖调解
- 第一原则,路径最近者优先;例子:A->B->C->X(1.0),A->D->X(2.0),X(1.0)路径是3,而X(2.0)路径是2,因此X(2.0)会被解析使用;
- 第二原则,路径相同时,第一声明者优先;例子:A->B-Y(1.0),A->C->Y(2.0),路径相同,都是2,Y(1.0)先声明,就会被优先解析使用;
4、优化依赖
- mvn dependency:list 查看当前项目已解析的依赖;
- mvn dependency:tree 查看当前项目的依赖树;
- mvn dependency:analyze 分析工具分析当前项目的依赖;
5、从仓库解析依赖的机制
当本地仓库没有依赖构件的时候,Maven自动从远程仓库下载;当依赖快照版本的时候,maven会自动寻找最新的快照;依赖解析机制如下:
- 当依赖范围是system时,maven直接从本地文件系统解析构件;
- 根据坐标计算仓库路径后,尝试从本地仓库寻找构件,如果发现,就解析成功;
- 本地仓库不存在,如果依赖的版本是显式的发布版本构件,如1.2,2.1-beta-1,则遍历所有的远程仓库,发现后,下载并解析使用;
- 如果依赖的是RELEASE或LATEST,则基于更新策略读取所有远程仓库的元数据group/artifactId/version/maven-metadata.xml,将其与本地仓库的对应元数据合并后,计算RELEASE或LATEST真实的值,基于这个真实值检查本地仓库和远程仓库,如步骤2,3
- 如果依赖是SNAPSHOT,则基于更新策略读取所有远程仓库的元数据group/artifactId/version/maven-metadata.xml,将其与本地仓库的对应元数据合并后,得到最新快照版本的值,然后基于该值检查本地仓库,或从远程仓库下载;
- 如果最后解析得到的构件版本是时间戳格式的快照,如1.4-1-20091104,则复制器时间戳格式的文件只费时间戳格式 如SNAPSHOT,并使用该非时间戳格式的构件。
- 当依赖的版本不明晰的时候,如RELEASE、LATEST、SNAPSHOT,Maven就需要基于更新远程仓库的更新策略来检查更新;
<!-- 当你更新了a-snapshot.jar的内容,并上传到maven服务器时,会更新一个元数据文件
maven-metadata.xml,这个文件内容类似如下 -->
<?xml version="1.0" encoding="UTF-8"?>
<metadata modelVersion="1.1.0">
<groupId>com.my.testu</groupId>
<artifactId>a</artifactId>
<version>1.0.1-SNAPSHOT</version>
<versioning>
<snapshot>
<timestamp>20160909.081828</timestamp>
<buildNumber>34</buildNumber>
</snapshot>
<lastUpdated>20160909081828</lastUpdated>
<snapshotVersions>
<snapshotVersion>
<extension>jar</extension>
<value>1.0.1-20160909.081828-34</value>
<updated>20160909081828</updated>
</snapshotVersion>
<snapshotVersion>
<extension>pom</extension>
<value>1.0.1-20160909.081828-34</value>
<updated>20160909081828</updated>
</snapshotVersion>
</versioning>
</metadata>