Maven简介、安装、使用、依赖传递
Maven
- 1 为什么要使用Maven
- 2 什么是Maven
- 2.1 构建
- 2.2 依赖
- 3 maven的工作机制
- 4 Maven的安装与配置
- 4.1 官网地址下载
- 4.2 环境变量的配置
- 4.3 maven本地仓库和镜像的配置
- 5 Maven中jar包的存储路径
- 5.1 Maven中的坐标
- 6 Maven核心概念:POM
- ①含义
- ②模型化思想
- ③对应的配置文件
- 7 Maven核心概念:约定的目录结构
- ①各个目录的作用
- ②约定目录结构的意义
- ③约定大于配置
- 8 Maven的一些常用命令
- 8.1 执行命令前的要求
- 8.2 清理操作
- 8.3 编译操作
- 8.4 测试操作
- 8.5 安装操作
- 9 依赖
- 9.1 查看依赖的jar包命令
- 9.2 依赖的范围
- ①compile 和 test 对比
- ②compile 和 provided 对比
- ③结论
- 9.3 依赖的传递性
- 1、依赖的传递性
- ①概念
- ②传递的原则
- 2、依赖传递测试
- 10 Maven的几个打包命令
1 为什么要使用Maven
- maven可以作为依赖管理工具
-
- 项目中需要引入的各种jar包非常多,自己管理非常麻烦;有了maven可以直接在pom文件中,写入对应的依赖项,maven自动帮我们配置下载
-
- jar包的下载也没有那么方便,而使用 Maven 后,可以根据具体的名称、版本、具体细节依赖对应的 jar 包,能够自动下载,方便、快捷又规范
-
- jar包之间的依赖关系也是非常复杂的,有时也会出现一些冲突;而maven可以帮我们管理这些依赖
2 什么是Maven
Maven 是 Apache 软件基金会组织维护的一款专门为 Java 项目提供构建和依赖管理支持的工具。
2.1 构建
- 构建过程包含的主要的环节:
-
- 清理:删除上一次构建的结果,为下一次构建做好准备
-
- 编译:Java 源程序编译成 *.class 字节码文件
-
- 测试:运行提前准备好的测试程序
-
- 报告:针对刚才测试的结果生成一个全面的信息
-
- 打包
-
-
- Java工程:jar包
-
-
-
- Web工程:war包
-
-
- 安装:把一个 Maven 工程经过打包操作生成的 jar 包或 war 包存入 Maven 仓库
-
- 部署
-
-
- 部署 jar 包:把一个 jar 包部署到 Nexus 私服服务器上
-
-
-
- 部署 war 包:借助相关 Maven 插件(例如 cargo),将 war 包部署到 Tomcat 服务器上
-
2.2 依赖
- 如果 A 工程里面用到了 B 工程的类、接口、配置文件等等这样的资源,那么我们就可以说 A 依赖 B
- 依赖管理中要解决的具体问题:
-
- jar 包的下载:使用 Maven 之后,jar 包会从规范的远程仓库下载到本地
-
- jar 包之间的依赖:通过依赖的传递性自动完成
-
- jar 包之间的冲突:通过对依赖的配置进行调整,让某些jar包不会被导入
3 maven的工作机制
4 Maven的安装与配置
4.1 官网地址下载
Maven官网链接
因为我是在linux服务器上使用,所以下载如下
4.2 环境变量的配置
我是在/etc/profile.d/myenv.sh新建了一个myenv.sh专门用于添加我安装软件的环境变量
也可以直接在/etc/profile中添加
sudo vim /etc/profile.d/myenv.sh
# 添加如下
# MAVEN_HOME
export MAVEN_HOME=/opt/apache-maven-3.8.6
export PATH=$PATH:$MAVEN_HOME/bin
source /etc/profile # 环境变量就生效了
需要注意的是,安装maven之前必须安装java
4.3 maven本地仓库和镜像的配置
- maven的目录
drwxr-xr-x 2 nowcoder1 nowcoder 4096 Oct 1 17:09 bin
drwxr-xr-x 2 nowcoder1 nowcoder 4096 Oct 1 17:09 boot
drwxr-xr-x 3 nowcoder1 nowcoder 4096 Oct 16 23:16 conf
drwxr-xr-x 4 nowcoder1 nowcoder 4096 Oct 1 17:09 lib
-rw-r--r-- 1 nowcoder1 nowcoder 17568 Jun 7 00:16 LICENSE
-rw-r--r-- 1 nowcoder1 nowcoder 5141 Jun 7 00:16 NOTICE
-rw-r--r-- 1 nowcoder1 nowcoder 2612 Jun 7 00:16 README.txt
- 进入conf目录下
drwxr-xr-x 2 nowcoder1 nowcoder 4096 Jun 7 00:16 logging
-rw-r--r-- 1 nowcoder1 nowcoder 10702 Oct 16 23:16 settings.xml
-rw-r--r-- 1 nowcoder1 nowcoder 3747 Jun 7 00:16 toolchains.xml
- 修改settings.xml
-
- 设置本地仓库位置
<!-- 设置本地仓库位置 -->
<localRepository>D:\maven-repository</localRepository>
-
- 设置远程仓库镜像
-
-
- Maven 下载 jar 包默认访问境外的中央仓库,而国外网站速度很慢。改成阿里云提供的镜像仓库,访问国内网站,可以让 Maven 下载 jar 包的时候速度更快
-
<mirrors>
<!-- mirror
| Specifies a repository mirror site to use instead of a given repository. The repository that
| this mirror serves has an ID that matches the mirrorOf element of this mirror. IDs are used
| for inheritance and direct lookup purposes, and must be unique across the set of mirrors.
|
<mirror>
<id>mirrorId</id>
<mirrorOf>repositoryId</mirrorOf>
<name>Human Readable Name for this Mirror.</name>
<url>http://my.repository.com/repo/path</url>
</mirror>
-->
<mirror>
<id>aliyunmaven</id>
<mirrorOf>*</mirrorOf>
<name>阿里云公共仓库</name>
<url>https://maven.aliyun.com/repository/public</url>
</mirror>
</mirrors>
5 Maven中jar包的存储路径
5.1 Maven中的坐标
[1] 说明
使用三个『向量』在『Maven的仓库』中唯一的定位到一个『jar』包。
- groupId:公司或组织的 id
- artifactId:一个项目或者是项目中的一个模块的 id
- version:版本号
[2] 取值方式
- groupId:公司或组织域名的倒序,通常也会加上项目名称
-
- 例如:com.atguigu.maven
- artifactId:模块的名称,将来作为 Maven 工程的工程名
- version:模块的版本号,根据自己的需要设定
-
- 例如:SNAPSHOT 表示快照版本,正在迭代过程中,不稳定的版本
-
- 例如:RELEASE 表示正式版本
[3] 坐标和仓库中 jar 包的存储路径之间的对应关系
坐标
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>2.5</version>
对应的仓库存储路径
Maven本地仓库根目录\javax\servlet\servlet-api\2.5\servlet-api-2.5.jar
6 Maven核心概念:POM
①含义
POM:Project Object Model,项目对象模型。和 POM 类似的是:DOM(Document Object Model),文档对象模型。它们都是模型化思想的具体体现。
②模型化思想
POM 表示将工程抽象为一个模型,再用程序中的对象来描述这个模型。这样我们就可以用程序来管理项目了。我们在开发过程中,最基本的做法就是将现实生活中的事物抽象为模型,然后封装模型相关的数据作为一个对象,这样就可以在程序中计算与现实事物相关的数据。
③对应的配置文件
POM 理念集中体现在 Maven 工程根目录下 pom.xml 这个配置文件中。所以这个 pom.xml 配置文件就是 Maven 工程的核心配置文件。其实学习 Maven 就是学这个文件怎么配置,各个配置有什么用。
7 Maven核心概念:约定的目录结构
①各个目录的作用
另外还有一个 target 目录专门存放构建操作输出的结果。
②约定目录结构的意义
Maven 为了让构建过程能够尽可能自动化完成,所以必须约定目录结构的作用。
- 例如:Maven 执行编译操作,必须先去 Java 源程序目录读取 Java 源代码,然后执行编译,最后把编译结果存放在 target 目录。
③约定大于配置
Maven 对于目录结构这个问题,没有采用配置的方式,而是基于约定。这样会让我们在开发过程中非常方便。如果每次创建 Maven 工程后,还需要针对各个目录的位置进行详细的配置,那肯定非常麻烦。
目前开发领域的技术发展趋势就是:约定大于配置,配置大于编码。
8 Maven的一些常用命令
8.1 执行命令前的要求
运行 Maven 中和构建操作相关的命令时,必须进入到 pom.xml 所在的目录
8.2 清理操作
mvn clean # 效果:删除 target 目录
8.3 编译操作
# 主程序编译:
mvn compile
# 测试程序编译:
mvn test-compile
# 主体程序编译结果存放的目录:
target/classes
# 测试程序编译结果存放的目录:
target/test-classes
8.4 测试操作
mvn package
# 打包的结果——jar 包,存放的目录:target
8.5 安装操作
mvn install
安装的效果是
- 将本地构建过程中生成的 jar 包存入 Maven 本地仓库。
- 这个 jar 包在 Maven 仓库中的路径是根据它的坐标生成的
- 然后其他的项目也可以使用这个jar包
安装操作还会将 pom.xml 文件转换为 XXX.pom 文件一起存入本地仓库。
- 所以我们在 Maven 的本地仓库中想看一个 jar 包原始的 pom.xml 文件时,查看对应 XXX.pom 文件即可,它们是名字发生了改变,本质上是同一个文件。
9 依赖
9.1 查看依赖的jar包命令
mvn dependency:list # 列表形显示
mvn dependency:tree # 树形显示
9.2 依赖的范围
①compile 和 test 对比
main目录(空间) | test目录(空间) | 开发过程(时间) | 部署到服务器(时间) | |
---|---|---|---|---|
compile | 有效 | 有效 | 有效 | 有效 |
test | 无效 | 有效 | 有效 | 无效 |
②compile 和 provided 对比
main目录(空间) | test目录(空间) | 开发过程(时间) | 部署到服务器(时间) | |
---|---|---|---|---|
compile | 有效 | 有效 | 有效 | 有效 |
provided | 有效 | 有效 | 有效 | 无效 |
③结论
[1] compile
- 通常使用的第三方框架的 jar 包这样在项目实际运行时真正要用到的 jar 包都是以 compile 范围进行依赖的。比如 SSM 框架所需jar包。
[2] test
- 测试过程中使用的 jar 包,以 test 范围依赖进来。比如 junit。
[3] provided
- 在开发过程中需要用到的“服务器上的 jar 包”通常以 provided 范围依赖进来。
- 比如 servlet-api、jsp-api。而这个范围的 jar 包之所以不参与部署、不放进 war 包,就是避免和服务器上已有的同类 jar 包产生冲突,同时减轻服务器的负担。说白了就是:“服务器上已经有了,你就别带啦!”
9.3 依赖的传递性
1、依赖的传递性
①概念
A 依赖 B,B 依赖 C,那么在 A 没有配置对 C 的依赖的情况下,A 里面能不能直接使用 C?
②传递的原则
在 A 依赖 B,B 依赖 C 的前提下,C 是否能够传递到 A,取决于 B 依赖 C 时使用的依赖范围。
- B 依赖 C 时使用 compile 范围:可以传递
- B 依赖 C 时使用 test 或 provided 范围:不能传递,所以需要这样的 jar 包时,就必须在需要的地方明确配置依赖才可以。
2、依赖传递测试
- 测试方式:
-
- pro03-maven-web在pom.xml中已经依赖pro01-maven-java了
-
- 现在我们让 pro01-maven-java 工程依赖三个不同范围的
- 具体操作:编辑 pro01-maven-java 工程根目录下 pom.xml
- 注意这里,pro01-maven-java 修改pom之后要mvn install一下
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>4.0.0.RELEASE</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.58</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.16</version>
<scope>provided</scope>
</dependency>
测试结果
- pro01-maven-java的依赖
[INFO] com.atguigu.maven:pro01-maven-java:jar:1.0-SNAPSHOT
[INFO] +- org.springframework:spring-core:jar:4.0.0.RELEASE:compile
[INFO] | \- commons-logging:commons-logging:jar:1.1.1:compile
[INFO] +- com.alibaba:fastjson:jar:1.2.58:test
[INFO] +- mysql:mysql-connector-java:jar:8.0.16:provided
[INFO] | \- com.google.protobuf:protobuf-java:jar:3.6.1:provided
[INFO] \- junit:junit:jar:4.12:test
[INFO] \- org.hamcrest:hamcrest-core:jar:1.3:test
- pro03-maven-web的依赖
[INFO] --- maven-dependency-plugin:2.8:tree (default-cli) @ pro03-maven-web ---
[INFO] com.atguigu.maven:pro03-maven-web:war:1.0-SNAPSHOT
[INFO] +- javax.servlet:javax.servlet-api:jar:3.1.0:provided
[INFO] +- com.atguigu.maven:pro01-maven-java:jar:1.0-SNAPSHOT:compile
[INFO] | \- org.springframework:spring-core:jar:4.0.0.RELEASE:compile
[INFO] | \- commons-logging:commons-logging:jar:1.1.1:compile
[INFO] \- junit:junit:jar:4.11:test
[INFO] \- org.hamcrest:hamcrest-core:jar:1.3:test
- 结论
pro01-maven-java 依赖的包 | 依赖的范围 | pro03-maven-web结果 |
---|---|---|
spring-core | compile | 有 |
fastjson | test | 没有 |
mysql-connector-java | provided | 没有 |
10 Maven的几个打包命令
- package命令:完成项目编译、单元测试、打包功能,但打包文件未部署到本地Maven仓库和远程Maven仓库。
- install命令:完成项目编译、单元测试、打包功能,同时把打包文件部署到本地Maven仓库,但未部署到远程Maven仓库。
- deploy命令:完成项目编译、单元测试、打包功能,同时把打包文件部署到本地Maven仓库和远程Maven仓库。
- 注意:
maven下载jar包时就存储在仓库里面了,而以下操作是把整个项目打包成一个jar包中存储在仓库中