1. maven中依赖范围
首先需要知道,maven在编译项目主代码的时候需要使用一一套classpath。其次,maven在编译和执行测试的时候会使用另外一套classpath。运行项目又会使用另一套classpath。
依赖范围就是用来控制依赖与这三种classpath(编译classpath、测试classpath、运行classpath)的关系。maven有以下几种依赖范围:
- compile:编译依赖范围。如果没有指定,就会默认使用该依赖范围。使用次依赖范围,对于编译、测试和运行三种classpath都有效。典型的例子就是spring-core,在编译、测试和运行的时候都需要使用此依赖。
- test:测试依赖范围。使用次依赖范围只对测试classpath有效,在编译主代码或者运行项目时无法使用此类依赖,典型例子:JUnit。
- provided:已提供依赖范围。使用次依赖范围,对于编译和测试classpath有效。但在运行时无效。典型例子:servlet-api,编译和测试项目的时候都需要该依赖,但是运行项目的时候,由于容器已经提供,就不需要maven重复的引入。
- runtime:运行时依赖范围,使用此依赖范围,对于测试和运行classpath都是有效,但在编译时无效。典型例子:JDBC驱动,项目主代码的编译只需要JDK提供的JDBC接口,只有在执行测试或者运行项目的时候才需要实现上述接口的具体JDBC驱动。
- system:系统依赖范围。该依赖与三种classpath的关系和provided依赖范围完全一致。但是,使用system范围依赖时必须通过systemPath元素显式地指定依赖文件的路径。由于此类依赖不是通过maven仓库解析的,而且往往与本机系统绑定,可能造成构建的不可移植,因此应该慎用。systemPath元素可以引用环境变量。
- import(Maven2.0.9及以上):导入依赖范围,该依赖不会对三种classpath产生实际影响。
依赖范围与classpath关系图
依赖范围 | 编译classpath | 测试classpath | 运行classpath | 例子 |
---|---|---|---|---|
compile | Y | Y | Y | spring-core |
test | N | Y | N | JUnit |
provided | Y | Y | N | serlvet-api |
runtime | N | N | Y | JDBC驱动实现 |
system | Y | Y | N | 本地的,maven仓库之外的类库文件 |
2.传递性依赖和依赖范围
最左边一行表示第一直接依赖范围,最上面一行表示第二直接依赖范围,中间交叉单元格则表示传递性依赖范围。
第一依赖范围列 | compile | test | provided | runtime |
---|---|---|---|---|
compile | compile | - | - | runtime |
test | test | - | - | test |
provided | provided | - | provided | provided |
runtime | runtime | - | - | runtime |
3.依赖调解
maven引入的传递性依赖机制,一方面大大简化和方便了依赖声明,另一方面,大部分情况下我们只需要关心项目的直接依赖是什么,而不用考虑这些直接依赖会引入什么传递依赖。但是有时候,当传递依赖造成问题时,我们就需要清楚的知道该传递依赖是从哪条依赖路径引入。
maven依赖调解原则:
- 路径最近者优先。
- 第一声明者优先
在依赖路劲长度相等的前提下,在POM中依赖声明的顺序决定了谁会被解析使用,顺序最靠前的那个依赖优胜。
4.maven生命周期
maven有三个内置生命周期:清理(clean)、默认(default)和站点(site)。clean生命周期处理项目的清理,default的生命周期处理项目部署,site生命周期处理项目站点文件创建。
- clean生命周期
事件 | 描述 |
---|---|
预清理(pre-clean) | 执行实际项目清理之前所需的流程 |
清理(clean) | 删除以前构建生成的所有文件 |
清理后处理(post-clean) | 执行完成项目清理所需的流程 |
- default生命周期
事件 | 描述 |
---|---|
验证(validate) | 验证项目正确,所有必要信息可用 |
初始化(initialize) | 初始化构建状态,例如设置属性或创建目录 |
产生来源(generate-sources) | 生成包含在编译中的任何源代码 |
处理源代码(process-sources) | 处理源代码,例如过滤任何值 |
生成资源(generate-resources) | 生成资源文件 |
流程资源(process-resources) | 将资源复制并处理到目标目录中,准备打包。 |
编译(compile) | 编译项目的源代码。 |
工艺类(process-classes) | 从编译后处理生成的文件,例如对Java类进行字节码增强。 |
生成测试来源(generate-test-sources) | 生成包含在编译中的任何测试源代码。 |
流程测试来源(process-test-sources) | 处理测试源代码,例如过滤任何值。 |
生成测试资源(generate-test-resources) | 创建测试资源。 |
流程测试资源(process-test-resources) | 将资源复制并处理到测试目标目录中。 |
测试编译(test-compile) | 将测试源代码编译到测试目标目录中 |
流程检验类(process-test-classes) | 从测试编译中处理生成的文件,例如对Java类进行字节码增强。对于Maven 2.0.5及以上版本。 |
测试(test) | 使用合适的单元测试框架运行测试。这些测试不应该要求代码被打包或部署。 |
制备包(prepare-package) | 在实际包装之前,执行必要的准备包装的操作。这通常会导致打包的处理版本的包。(Maven 2.1及以上) |
打包(package) | 采取编译的代码,并以其可分发的格式(如JAR)进行打包。 |
预集成测试(pre-integration-test) | 在执行集成测试之前执行所需的操作。这可能涉及诸如设置所需环境等。 |
集成测试(integration-test) | 如果需要,可以将该包过程并部署到可以运行集成测试的环境中。 |
整合后的测试(post-integration-test) | 执行集成测试后执行所需的操作。这可能包括清理环境。 |
校验(verify) | 运行任何检查以验证包装是否有效并符合质量标准。 |
安装(install) | 将软件包安装到本地存储库中,以作为本地其他项目的依赖关系。 |
部署(deploy) | 在集成或发布环境中完成,将最终软件包复制到远程存储库,以与其他开发人员和项目共享。 |
- site生命周期
事件 | 描述 |
---|---|
pre-site | 项目site生成前处理 |
site | 生成项目site文档 |
post-site | 后处理 |
site-deploy | 将生成的site文档部署到指定的web服务器上 |