构建工具Maven
Maven项目对象模型(POM),可以通过一小段描述信息来管理项目的构建,报告和文档的项目管理工具软件。
Maven 除了以程序构建能力为特色之外,还提供高级项目管理工具。由于 Maven 的缺省构建规则有较高的可重用性,所以常常用两三行 Maven 构建脚本就可以构建简单的项目。由于 Maven 的面向项目的方法,许多 Apache Jakarta 项目发文时使用 Maven,而且公司项目采用 Maven 的比例在持续增长。
参考文章:Maven基础&MyBatis
Maven简介
Maven是专门用于管理和构建Java项目的工具。
传统项目管理缺点:
- jar包版本不统一、不兼容
 - 工程升级维护过程操作繁琐
 
Maven介绍:
Maven 的本质是一个项目管理工具,将项目开发和管理过程抽象成一个项目对象模型(POM)。
maven是用java语言写的,它管理的项目都以面对对象形式设计,最终把一个项目看成一个对象,即POM。
**POM:**(Project Object Model):项目对象模型
作用和功能
作用:
- 项目构建:提供标准的、跨平台的自动化项目构建方式
 - 依赖管理:方便快捷的管理项目依赖的资源(jar包),避免资源间的版本冲突问题
 - 统一开发结构:提供标准的、统一的项目结构
 
功能:Maven是专门用于管理和构建Java项目的工具,它的主要功能有:
提供了一套标准化的项目结构
每一个开发工具(IDE)都有自己不同的项目结构,它们互相之间不通用。
而Maven提供了一套标准化的项目结构,所有的IDE使用Maven构建的项目完全一样,所以IDE创建的Maven项目可以通用。
提供了一套标准化的构建流程
编译,测试,打包,发布……
提供了一套依赖管理机制
Maven使用标准的坐标配置来管理各种依赖, 只需要简单的配置就可以完成依赖管理
Maven模型
- 项目对象模型pom (Project Object Model)
 - 依赖管理模型(Dependency)
 - 插件(Plugin)
 

项目对象模型pom就是将我们自己抽象成一个对象模型,有自己专属的坐标,是唯一标识。
项目对象模型pom通过xml格式保存的pom.xml文件。该文件用于管理:源代码、配置文件、开发者的信息和角色、问题追踪系统、组织信息、项目授权、项目的url、项目的依赖关系等等。
1  | <groupId>org.example</groupId>  | 
依赖管理模型则是使用坐标来描述当前项目依赖哪些第三方jar包
1  | <dependency>  | 
项目管理模型和依赖管理模型结合起来,体现Maven方便的依赖管理。
构建生命周期和插件部分用来完成 标准化构建流程 。
如我们需要编译,Maven提供了一个编译插件供我们使用。我们需要打包,Maven就提供了一个打包插件提供我们使用等。
仓库
Maven用坐标配置管理依赖。
依赖jar包则其实存储在本地仓库中,项目运行时从本地仓库中拿需要的依赖jar包。
- 本地仓库:自己电脑上存储资源的仓库(是个目录),连接远程仓库获取资源
 - 中央仓库:由Maven团队维护的全球唯一的仓库,Maven团队维护,存储所有资源的仓库
 - **远程仓库(私服)**:一般由公司团队搭建的私有仓库。部门/公司范围内存储资源的仓库,从中央仓库获取资源
 
私服的作用:
- 保存具有版权的资源,包含购买或自主研发的jar。中央仓库中的jar都是开源的,不能存储具有版权的资源
 - 一定范围内共享资源,仅对内部开放,不对外共享
 
当项目中使用坐标引入对应依赖jar包后,首先会查找本地仓库中是否有对应的jar包:
- 如果有,则在项目直接引用;
 - 如果没有,则去中央仓库中下载对应的jar包到本地仓库。
 

如果还可以搭建远程仓库,将来jar包的查找顺序则变为:
本地仓库 –> 远程仓库–> 中央仓库

Maven 坐标详解
什么是坐标?
- Maven 中的坐标是资源的唯一标识
 - 使用坐标来定义项目或引入项目中需要的依赖
 
所有坐标官网(需要梯子):Maven Repository
Maven 坐标主要组成
groupId:定义当前Maven项目隶属组织名称(通常是域名反写,例如:com.itheima)
artifactId:定义当前Maven项目名称(通常是模块名称,例如 order-service、goods-service)
version:定义当前项目版本号
scope:范围,像Servlet、jsp依赖都需要设置范围为provided
1  | <dependency>  | 
注意:
- 上面所说的资源可以是插件、依赖、当前项目。
 - 我们的项目如果被其他的项目依赖时,也是需要坐标来引入的。
 
Maven基本使用
Maven常用命令
compile :编译,生成target目录
clean:清理,删除target目录
test:测试,执行test文件下测试代码
package:打包,将当前项目打包成的jar包
install:安装,将当前项目打成jar包,并安装到本地仓库

编译命令 mvn compile
首次编译会先从阿里云(之前conf/settings.xml配置了阿里云私服)下载编译需要插件的jar包,在本地仓库(之前conf/settings.xml配置了本地仓库位置)也能看到下载好的插件。
在项目下会生成一个 target 目录,里面保存编译后的字节码文件。
清理命令 mvn clean
- 从阿里云下载清理需要的插件jar包
 - 删除项目下的 
target目录 
Maven 生命周期
简洁版:
- clean:清理上次构建结果
 - valide:校验工程信息是否正确
 - comple:编译工程
 - test:执行工程测试流程(标注的test的程序)
 - package:打包工程
 - verify:验证包的有效性
 - install:安装包到本地仓库
 - deploy:推送包到远程仓库
 
Maven 构建项目生命周期描述的是一次构建过程经历经历了多少个事件
Maven 对项目构建的生命周期划分为3套:
- clean :项目清理的处理,移除所有上一次构建生成的文件。
 - default(或 build) :核心工作,例如编译,测试,打包,安装等。
 - site : 产生报告,发布站点等。这套生命周期一般不会使用。
 
Clean 生命周期
执行 mvn post-clean 命令时,Maven 调用 clean 生命周期,它包含以下阶段:
- pre-clean:执行一些需要在clean之前完成的工作
 - clean:移除所有上一次构建生成的文件
 - post-clean:执行一些需要在clean之后立刻完成的工作
 
default生命周期
| 阶段 | 处理 | 描述 | 
|---|---|---|
| 验证 validate | 验证项目 | 验证项目是否正确且所有必须信息是可用的 | 
| 编译 compile | 执行编译 | 源代码编译在此阶段完成 | 
| 测试 Test | 测试 | 使用适当的单元测试框架(例如JUnit)运行测试。 | 
| 包装 package | 打包 | 创建JAR/WAR包如在 pom.xml 中定义提及的包 | 
| 检查 verify | 检查 | 对集成测试的结果进行检查,以保证质量达标 | 
| 安装 install | 安装 | 安装打包的项目到本地仓库,以供其他项目使用 | 
| 部署 deploy | 部署 | 拷贝最终的工程包到远程仓库中,以共享给其他开发人员和工程 | 
注意:
- 打包前先clean是好习惯,能够保证上一次构建的输出不会影响到本次构建。
 - 同一套生命周期内,执行后边的命令,前面的所有命令会自动执行。例如执行安装会先执行打包。
 
site构建生命周期:
- pre-site:执行一些需要在生成站点文档之前完成的工作
 - site:生成项目的站点文档
 - post-site: 执行一些需要在生成站点文档之后完成的工作,并且为部署做准备
 - site-deploy:将生成的站点文档部署到特定的服务器上
 
pom文件配置编码及JDK版本
在pom.xml配置如下代码,适用于项目要在不同项目移动:
1  | <properties>  | 
Maven依赖管理
依赖概述
依赖指当前项目运行所需的jar,一个项目可以设置多个依赖。
groupId:依赖所属群组id。
artifactId:依赖所属项目id。
version:依赖版本号。
scope:依赖生效范围。
optional:为true时是可选依赖,指对外隐藏当前所依赖的资源——不透明。设置后其他依赖引用本项目时候将无法看到这个依赖。控制别人能不能看到你用到你。
exclusions-exclusion:排除依赖指主动断开依赖的资源,被排除的资源无需指定版本。控制你引用的项目中需要排除的依赖。
依赖范围scope
依赖的jar默认在任何地方使用,通过scope便签设定其范围。
通过设置坐标的依赖范围(scope),可以设置对应jar包的作用范围:编译环境、测试环境、运行环境。
如下图所示给 junit 依赖通过 scope 标签指定依赖的作用范围。 那么这个依赖就只能作用在测试环境,其他环境下不能使用。
1  | <dependency>  | 
依赖范围scope可取值:
| 依赖范围 | 编译classpath | 测试classpath | 运行classpath | 例子 | 
|---|---|---|---|---|
| compile | Y | Y | Y | logback | 
| test | - | Y | - | Junit | 
| provided | Y | Y | - | servlet-api | 
| runtime | - | Y | Y | jdbc驱动 | 
| system | Y | Y | - | 存储在本地的jar包 | 
配置后可以在依赖中看到:org.mybatis:mybatis:3.5.3 (runtime)
依赖具有传递性
直接依赖:在当前项目中通过依赖配置建立的依赖关系
间接依赖:被资源的资源如果依赖其他资源,当前项目间接依赖其他资源
依赖传递冲突问题
路径优先:当依赖中出现相同的资源时,层级越深,优先级越低,层级越浅,优先级越高
声明优先:当资源在相同层级被依赖时,配置顺序靠前的覆盖配置顺序靠后的
特殊优先:当同级配置了相同资源的不同版本,后配置的覆盖先配置的
可选依赖optional
可选依赖指对外隐藏当前所依赖的资源——不透明
1  | <dependency>  | 
排除依赖exclusions-exclusion
排除依赖指主动断开依赖的资源,被排除的资源无需指定版本
1  | <dependency>  | 
依赖jar包引用,设置自动刷新
使用坐标引入依赖的jar包
在项目的 pom.xml 中编写
<dependencies>标签在
<dependencies>标签中 使用<dependency>引入坐标定义坐标的 groupId,artifactId,version
groupId:定义当前Maven项目隶属的实际项目。
例如org.sonatype.nexus,此id前半部分org.sonatype代表此项目隶属的组织或公司,后部分代表项目的名称。
如果此项目多模块话开发的话就子模块可以分为org.sonatype.nexus.plugins和org.sonatype.nexus.utils等。特别注意的是groupId不应该对应项目隶属的组织或公司,也就是说groupId不能只有org.sonatype而没有nexus。
artifactId:构件ID。该元素定义实际项目中的一个Maven项目或者是子模块,如上面官方约定中所说,构建名称必须小写字母,没有其他的特殊字符,推荐使用“实际项目名称-模块名称”的方式定义,例如:spirng-mvn、spring-core等。
快捷方式引入jar包
- 在 pom.xml 中 按 alt + insert,选择 Dependency
 - 在弹出的面板中搜索对应坐标,然后双击选中对应坐标
 - 点击刷新按钮,使坐标生效
 
插件
- 插件与生命周期内的阶段绑定,在执行到对应生命周期时执行对应的插件功能。
 - 默认maven在各个生命周期上绑定有预设的功能。
 - 通过插件可以自定义其他功能。
 
示例:Tomcat部署的插件
1  | <build>  | 



