Maven 简明笔记
Maven 主要功能
Maven 是专门用于管理和构建 Java 项目的工具,它的主要功能有:
- 提供了一套标准化的项目结构
- 提供了一套标准化的构建流程(编译,测试,打包,发布…)
- 提供了一套依赖管理机制
标准化的项目结构
不同 IDE 之间,项目结构不一样,不通用
所有 IDE 使用 Maven 构建的项目结构完全一样,所有 IDE 创建的 Maven 项目都可以通用
Maven 的项目结构
标准化的构建流程
源代码⇒编译⇒测试⇒打包⇒发布,Maven 提供了一套简单的命令来完成项目构建
提供了一套依赖管理机制
比如 JDBC,需要使用的 MySQL 的驱动包,依赖管理其实就是管理你项目所依赖的第三方资源(Jar 包、依赖),原先我们是如何操作的呢:
- 下载 jar 包
- 将 jar 包复制到 lib 文件夹里
- 右键 jar 包,作为库
那 Maven 是如何管理依赖的呢
- Maven 使用标准的 坐标 配置来管理各种依赖
- 只需要简单的配置就可以完成依赖管理
Maven 简介
Apache Maven 是一个项目管理和构建工具,它基于项目对象模型(POM)的概念,通过一小段描述信息来管理项目的构建、报告和文档
仓库分类
- 本地仓库
- 中央仓库:有 Maven 团队维护的全球唯一的仓库(免费的开源的 jar 包)
- 远程仓库(私服):一般有公司团队搭建的私有仓库(可以存放一下自己的公司的和一些可能具有版权的 jar 包)
查找流程:首先会查找本地仓库,如果本地仓库没有,则去中央仓库查找是否有,有的话就会 自动下载 到本地仓库
Maven 的安装和配置
- 解压即可安装
- 配置环境变量
下图中的 Maven 文件夹呢就是包含 bin 文件夹的文件夹
将 bin 目录添加到 Path 目录中
- 配置本地仓库:修改 conf/setting.xml 中的
<localRepository>
为其指定一个目录
注意:为了保守起见,在 Intellij 中也对 Maven 的本地路径配置一下:)
- 配置阿里云私服:修改 conf/setting.xml 中的
<mirrors>
标签,为其添加如下子标签
1 | <mirror> |
Maven 的基本使用
Maven 的常用命令
- compile:编译
- clean:清理,删除前面编译产生的 target 目录
- test:测试,执行 test 文件夹下的代码
- package:打包
- install:安装
在含有 pom.xml 文件的目录下,进入 PowerShell
1 | mvn compile |
Maven 的生命周期
Maven 对项目构建的生命周期划分为三套
- clean:清理工作
- default:核心工作,例如编译,测试,打包,安装等
- site:产生报告,发布站点等
比如说执行 install,就会自动执行 compile,但是不会自动执行 clean(因为这是两套不同的生命周期)
依赖管理
使用坐标导入 jar 包
- 在 pom.xml 中编写
<dependencies>
标签 - 在
<dependencies>
标签中使用<dependency>
来引入坐标 - 定义坐标的 groupId,artifactId,version
- 点击刷新按钮,是坐标生效(或者对 IDE 进行配置,每次变更自动生效)
1 | <!-- 导入 mysql 驱动jar包--> |
比如去找 MySQL 的 Maven 配置信息(浏览器搜索 mysql maven
),比如从以下网页中找到了:MySQL Connector Java
还为我们提供了 maven 需要使用的信息
快速导入坐标信息到 pom.xml
如果本地仓库就有相应的 jar 包,那么直接可以通过搜索 jar 包的名字来导入(即可自动导入模板)
- 在 pom.xml 文件中,Alt+Insert
- 选择依赖项模板,自动为我们添加模板
依赖范围
通过设置坐标依赖范围(scope),可以设置对应 jar 包的作用范围:编译环境、测试环境、运行环境
编译环境:在主工程 java 文件夹中可以使用
测试环境:在测试文件夹 test 中可以使用
运行环境:
依赖范围的取值有以下六种,默认值是 compile(其实范围也是最大的)
分模块开发与设计
将原始模块按照功能拆分为若干个子模块,方便模块间的相互调用,接口共享
Intellij 中同时导入多个模块方式如下:
1、项目准备:之前做好的 SSM 整合的项目 maven_02_ssm 进行讲解
2、新建一个模块:maven_03_pojo
1)新建 com.itheima.domain 包
2)将 maven_02_ssm 中的 domain 下的 Book 实体类剪切至 maven_03_pojo 下的 domain 包下
3)此时 maven_02_ssm 将无法运行,因为缺少了 Book 实体类
4)现在要做到是:如何在 maven_02_ssm 中访问 / 加载 maven_03_pojo 下的 Book 实体类呢?
maven_03_pojo 模块中 pom.xml 的坐标如下
1 | <groupId>com.itheima</groupId> |
那么我们在 maven_02_ssm 中引入上面的坐标
1 | <!--依赖domain运行--> |
此时就将 maven_03_pojo 模块引入进来了,此时 maven_02_ssm 也没有报错了
总结:将一个模块中的一部分功能抽取出来单独做一个模块,然后在原来的使用方去引用这个抽取出来的模块,这样就做成了两个模块
但是此时 02 模块会有问题?为什么呢
因为通过坐标导入,会将相应的资源下载到本地仓库,02 模块引入了 03 模块,但是本地仓库里面却找不到 03 的资源。因此,我们还需要将 03 模块 install 到本地仓库中
安装完之后,本地仓库中就可以找到模块 03 的资源了。此时我们在 compile 一下 02 模块,若能够编译成功,说明没有问题了
依赖管理
如果一个模块 A 依赖了模块 B,而 B 模块依赖了其他的东西,那么这个 A 模块可以直接使用这些东西
直接依赖:在当前项目中通过依赖配置建立的依赖关系
简介依赖:被依赖的资源如果依赖其他资源,当前项目简介依赖其他资源
依赖冲突
- 路径优先:当依赖中出现相同的资源时,层级越深,优先级越低,层级越浅,优先级越高
- 声明优先:当资源在相同层级被依赖时,配置顺序靠前的覆盖配置顺序靠后的
- 特殊优先:当同级配置类相同资源的不同版本,后配置的覆盖先配置的
可以通过此处查看项目中的依赖关系
可选依赖
比如说 02 模块引用了 04 模块,04 模块中引用了几个坐标。现在的需求是,我不想让 02 模块能够加载或引用 04 模块中的坐标,怎么处理呢?
那么在 04 模块中,对如下这个坐标进行处理
1 | <dependency> |
其实这个需要就是想要某个坐标没有传递性
排除依赖
比如引用了 maven_04_dao
坐标,但是排除这个坐标下的另外两个坐标
1 | <dependency> |
那么可选和排除有什么区别呢:
- 用的可选,别人引用了我的坐标,但是不知道我背后引用了哪些坐标;对外隐藏当前所依赖的资源
- 用的排除,别人是知道我背后引用了那些坐标的;主动断开依赖的资源,被排除的资源无需指定版本
聚合
比如:上面的三个模块都是依赖 pojo 模块的,假如我们更新了 pojo 模块,上面三个模块会及时更新吗?如果 pojo 因为更新出现了问题,上面三个模块能够及时发现吗?
聚合:将多个模块组织成一个整理,同时进行项目构建的过程称为聚合(其实有点像事务的概念)
聚合工程:通常是一个不具有业务功能的 “空” 工程(仅有一个 pom 文件)
作用:使用聚合工程可以将多个模块编组,通过对聚合工程进行构建,实现对所包含的模块进行同步构建;当工程中某个模块发生更新时,必须保障工程中与已更新模块关联的模块同步更新,此时可以使用聚合工程来解决批量模块同步构建的问题
1)创建新 Maven 模块
2)聚合工程的特点:在 pom.xml 中,将打包方式设置为 pom
1 | <packaging>pom</packaging> |
3)设置管理模块的模块名称
1 | <!--设置管理模块名称 |
4)进行同步编译 compile
继承
概念:继承描述的是两个工程间的关系,与 Java 中的继承相似,子工程可以继承父工程中的配置信息,常见于依赖关系的继承
作用:简化配置;减少版本冲突
1)继承关系在子类中描述
1 | <!--配置当前工程继承自parent工程--> |
此时,就可以继承父工程中依赖的坐标了
2)父工程中的坐标都必须要被所有子工程继承吗?不一定
可以在父工程 pom 文件中通过 dependencyManagement
来指定这是一个可选的坐标
1 | <!--定义依赖管理--> |
如果子工程中想要引用的话就在 pom 中加上相应的坐标,但是注意不要加版本号,因为他会自动继承父类中坐标的版本号;而对于其他子工程就不会自动继承引用这个坐标
1 | <dependency> |
3)子工程继承父工程中的坐标,只要父工程中坐标的版本号一改,所有子工程中对应的版本号都会改
聚合与继承的区别
- 作用
- 聚合用于快速构建项目
- 继承用于快速配置
- 相同点
- 聚合与继承的 pom.xml 文件打包方式均为 pom,可以将两种关系制作到同一个 pom 文件中
- 聚合与继承均属于设计型模块,并无实际的模块内容
- 不同点
- 聚合是在当前模块中配置关系,聚合可以感知到参与聚合的模块有哪些
- 继承是在子模块中配置关系,父模块无法感知哪些子模块继承了自己
属性
1)定义属性
1 | <!--定义属性,标签名可以自定义--> |
2)在定义坐标时,可以直接使用变量
1 | <dependency> |
3)这样就好了呀,以后可以直接从这儿就可以看到各种坐标的版本
1 | <!--定义属性--> |
版本管理
比如如下为某一工程 pom.xml 中的坐标,其中的 version 有什么用呢?
1 | <groupId>com.itheima</groupId> |
- 工程版本
- SNAPSHOT(快照版本)
- 项目开发过程中临时输出的版本,称为快照版本
- 快照版本会随着开发的进展不断更新
- RELESE(发布版本)
- 项目开发到进入阶段里程碑后,向团队外部发布较为稳定的版本,这种版本所对应的构建文件时稳定的,即便进行功能的后续开发,也不会改变当前发布版本的内容,这种版本称为发布版本
- SNAPSHOT(快照版本)
- 发布版本
- alpha 版
- beta 版
- 纯数字版
多环境配置
maven 提供配置多种环境的设定,帮助开发者使用过程中快速切换环境
1)在父工程 pom.xml 中
1 | <!--配置多环境--> |
2)对工程进行 install,然后可以查看项目构建好的 war 包,双击 war 包,进入 WEB-INF 文件夹 ⇒ classes 文件夹 ⇒ jdbc.properties 文件,查看配置是否生效
如果要更换环境,可以将设置默认启动环境的那几行代码切换一下位置,比如切换到测试环境中,那么 install 后,默认就是测试环境的配置了
或者可以不用挪动那几行代码,直接使用 Maven 指令来表明我们将使用 env_dep
环境来进行 install,如下图所示
跳过测试
跳过测试:跳过所有测试
跳过测试:指定跳过某些内容
1 | <build> |