1、maven的两大核心内容:
-
依赖管理:对 jar 的统一管理(Maven 提供了一个 Maven 的中央仓库,https://mvnrepository.com/ ,当我们在项目中添加完依赖之后,Maven 会自动去中央仓库下载相关的依赖,并且解决依赖的依赖问题。),也可以是自己的仓库。
-
项目构建:对项目进行编译、测试、打包、部署以及上传到私服等。
2、dependency:
- groupId(公司或组织域名倒序)
- artifactId(模块名,也是实际项目的名称)
- version(当前项目的版本)
以上三个部分组成了依赖的基本坐标,maven根据坐标才能找到具体的依赖。
3、maven依赖的传递性:即最短路径优先原则和最先声明原则。
- 最短路径原则
A -> B -> C -> D(V1)
F -> G -> D(V2)
假设test依赖于D,这时maven会采用最短路径原则,选择V2版本的D。
因为V1版本的D是由A包间接依赖的,整个依赖路径长度为3,而V2版本的D是由F包间接依赖的,整个依赖路径长度为2。
- 优先声明原则
A -> B -> D(V1)
F -> G -> D(V2)
如果两个jar包版本路径深度相同,maven会根据pom文件声明的顺序加载,使用优先声明的版本。
- 直引覆盖原则
多次直接引用不同版本的jar时,使用最后声明的版本。
4、依赖范围:(决定了你依赖进来的坐标,在什么情况下有效,什么情况下无效。
关键字:<scope>xxx</scope>
编译、测试、运行的意义:
- 编译:是指将整个项目(其实是模块)的 src/main/java 目录下的源代码文件以及 resources 目录下的资源文件编译输出到 classes 目录下。在这个编译过程中编译器会到 classpath 指定的目录下查找字节码文件(jar包、class文件等)
- 测试是指编译测试的代码和运行测试的代码,通常使用 Junit 工具进行代码的测试
- 运行是指项目部署到服务器,并且启动了服务器,客户端可以正常访问应用
compile:
编译依赖范围。如果没有指定,就会默认使用该依赖范围。使用此依赖范围的Maven 依赖,对于编译、测试、运行三种classpath 都有效。典型的例子是spring-core,在编译、测试和运行的时候都需要使用该依赖。
既然运行时也要使用 scope 设为 compile 的依赖,所以 scope 为 compile 的依赖在项目打部署包的时候(即构建 artifact)会被一起打包,会放在 WEB-INF/lib 目录下。
test:
测试依赖范围。使用此依赖范围的Maven依赖,只对于测试classpath有效,在编译主代码或者运行项目的使用时将无法使用此类依赖。典型的例子是JUnit,它只有在编译测试代码及运行测试的时候才需要。scope 为 test 的依赖只在测试时使用,用于编译和运行测试代码,不会参与项目的打包。
provided:
已提供依赖范围。使用此依赖范围的Maven依赖,对于编译和测试classpath有效,但在运行时无效(对运行的classpath无效)。典型的例子是 servlet-api, 编译和测试项目的时候需要该依赖,但在运行项目的时候,由于容器已经提供,就不需要Maven重复地引人一遍。既然运行时容器会提供,所以 scope 为 provided 的依赖不会参与项目的打包。
runtime:
运行时依赖范围。使用此依赖范围的Maven依赖,对于测试和运行class-path有效,但在编译主代码时无效(对编译的classpath无效)。典型的例子是JDBC驱动实现,项目主代码的编译只需要JDK提供的JDBC接口,只有在执行测试或者运行项目的时候才需要实现上述接口的具体JDBC驱动。
既然运行时也要使用 scope 设为 runtime 的依赖,所以 scope 为 runtime 的依赖在项目打部署包的时候(即构建 artifact)会被一起打包,会放在 WEB-INF/lib 目录下。
system:
系统依赖范围。该依赖与三种 classpath 的关系,和 provided 依赖范围完全一致。但是,system 范围的依赖不会从 maven 仓库下载,而是从本地文件系统获取,使用 system 范围的依赖时必须通过
<systemPath>
元素显式地指定依赖文件的路径。
由于此类依赖不是通过 Maven 仓库解析的,而且往往与本机系统绑定,可能造成构建(构建的产物有:classes和artifact)的不可移植,因此应该谨慎使用。
import:
导入依赖范围,该依赖范围不会对三种 classpath 产生影响,该依赖范围只能与
<dependencyManagement>
元素配合使用,其功能为将目标pom.xml 文件中元素<dependencyManagement>
的配置导入合并到当前 pom.xml 文件的元素<dependencyManagement>
中。有关元素<dependencyManagement>
的功能请了解 Maven 继承特性。
依赖范围与 classpath 的关系表:
5、maven 的 Lifecycle 里面的命令的解释:
-
clean:清除由项目编译创建的target。
-
validate:验证项目是否正确并且所有必要的信息均可用。
-
compile:编译项目的源代码。
-
test:使用合适的单元测试框架来测试编译的源代码。 这些测试不应要求将代码打包或部署。
-
verify:对集成测试的结果进行任何检查,以确保符合质量标准。
-
package:完成了项目编译、单元测试、打包功能,但没有把打好的可执行jar包(war包或其它形式的包)布署到本地maven仓库和远程maven私服仓库。
-
install:完成了项目编译、单元测试、打包功能,同时把打好的可执行jar包(war包或其它形式的包)布署到本地maven仓库,但没有布署到远程maven私服仓库。
-
deploy:完成了项目编译、单元测试、打包功能,同时把打好的可执行jar包(war包或其它形式的包)布署到本地maven仓库和远程maven私服仓库。
-
site:一般用来创建新的报告文档、部署站点等。