简介
maven主要服务于基于java平台的项目构建, 依赖管理和项目信息管理.
- maven是跨平台的.
- maven抽象了一个完整的构建生命周期模型, 并且为绝大部分构建任务提供了已实现的插件.
- maven标准化了构建过程.
maven项目的核心是pom.xml, POM(Project Object Model, 项目对象模型)定义了项目的基本信息, 用于描述项目如何构建, 声明项目依赖等等.
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<!--当前POM的版本, 对于maven2或maven3只能是4.0.0-->
<modelVersion>4.0.0</modelVersion>
<!--组, 项目所在的组织或公司的域名倒序-->
<groupId>com.greatonce</groupId>
<!--当前项目在组中的的唯一id, 为项目名或模块名-->
<artifactId>oms-three-service</artifactId>
<!--版本, SNAPSHOT快照, 意为项目还在开发中, 是不稳定的版本-->
<version>3.0-SNAPSHOT</version>
<!--声明一个对用户友好的项目名称, 一般不写-->
<name>oms3</name>
</project>
补充:
- maven打包会以artifactId-version.jar规则进行命名;
- install命令是将项目输出的jar安装到本地的maven仓库中, 这样其他项目中才能引用
- maven约定, 在项目根目录中创建pom.xml, 在src/main/java中放置主代码, 在src/test/java中放置测试代码等, 我们称这些基本的目录结构和pom.xml文件内容为项目的骨架, idea中可以选择对应archetype来创建maven项目
坐标和依赖
坐标元素
maven定义了这样一组规则: 世界上任何一个构件都可以使用maven坐标唯一标识.
maven坐标的元素包括:
- groupId, 定义当前Maven项目隶属的实际项目
- artifactId, 该元素定义实际项目中一个maven模块, 推荐做法是使用实际项目名称作为前缀, 比如spring-context
- version, 版本
- packaging(可选), 定义打包方式
- classfier(不能直接定义), 帮助定义构建输出的一些附属构件.
依赖的配置
<dependency>
<!--依赖的基本坐标-->
<groupId></groupId>
<artifactId></artifactId>
<version></version>
<!--依赖定义的类型, 对应项目坐标的packaging, 大部分情况下不必声明, 默认值为jar-->
<type></type>
<!--依赖范围-->
<scope></scope>
<!--依赖是否可选-->
<optional></optional>
<!--用来排除传递性依赖-->
<exclusions>
<exclusion>
<groupId></groupId>
<artifactId></artifactId>
</exclusion>
</exclusions>
</dependency>
依赖的范围
classPath补充: 参考: https://www.liaoxuefeng.com/wiki/1252599548343744/1260466914339296 https://blog.csdn.net/zhuhai__yizhi/article/details/78183311 classpath是JVM用到的一个环境变量,它用来指示JVM如何搜索class。 也可以说, classpath相当于Java执行环境,它指定了一些常用的包或jar的位置,方便我们对项目文件的使用,而不必重复多次写所需要文件的位置。 * 在classpath中可能需要使用所有相同名字的资源文件,如果用classpath:只会加载第一个,而使用classpath:前缀则能够加载所有符合类型的文件。然而,使用classpath:需要遍历所有的classpath,加载速度很慢,因此应该尽量避免使用classpath。
在idea中, target->classes即为classpath,任何我们需要在classpath前缀中获取的资源都必须在target->classes文件夹中找到,否则将出现java.io.FileNotFoundException的错误信息。
依赖传递
当既存在直接依赖, 又存在传递依赖时, 最终依赖范围计算规则如下图, 可见绝大多数情况, 传递性依赖范围与直接依赖范围相同.
依赖调解
当依赖版本冲突时, 依赖调解有俩规则:
- 路径最近者优先
例如: A->B->C(1.0), A->C(2.0), 最终依赖的C(2.0)
- 路径距离相同时, 第一声明优先
例如: A->C(1.0), A->C(2.0), 最终依赖的C(1.0)
可选依赖
A->B, B->X(可选), B->Y(可选), 项目B实现了多个特性, 因此声明了
- 可选依赖不会被传递
- A->B时, 实际使用哪个依赖, 需要在A中显示声明
其他特性
- 依赖排除
- 依赖归类(定义properties来统一依赖版本)
仓库
任何一个依赖, 插件或者项目构建的输出都可以称之为构件. 任何一组构件都有一组唯一标识.
仓库是maven统一存放构件的地方.
项目构建完毕后生成的构件也可以安装或部署到仓库中, 供其他项目使用.
maven文件的路径: groupId/artifactId/version/artifactId-version.packaging
仓库分类
补充: 私服是特殊的远程仓库, 为了节省带宽和时间, 在局域网内架设一个私有的仓库服务器, 用其代理所有的外部的远程仓库, 内部的项目还能部署到私服上供其他项目使用.
私服好处:
- 节省外网带宽
- 加速Maven构建
- 部署第三方构件
- 提高稳定性, 增强控制
- 降低中央仓库的负荷
配置远程仓库以及认证信息
示例, 配置pom使用JBOSS Maven仓库
示例, 配置认证信息, 注意此处的id和仓库的id绑定
部署至远程仓库
如下, 第一个表示发布版本构建的仓库, 第二个表示发布快照版本的仓库
注意, 需要配置认证信息, 截图略
配置完后, 运行mvn clean deploy , maven会将项目构建输出的构件部署至对应的远程仓库, 如果当前项目是快照版本, 则部署到快照版本仓库, 否则就部署到发布版本仓库.
快照版本
快照版本是为了解决内部协作时的依赖更新问题的, 在发布的过程中, maven会自动的为构件打上时间戳, 默认情况下, maven每天检查一次更新(由仓库的updatePolicy控制, 如下图), 也可以用命令行mvn clean install-U强制更新
快照版本只应该在组织内部的项目或模块间依赖使用.
镜像
如果仓库X可以存储仓库Y的所有内容, 那么就可以认为X是Y的一个镜像.
如下示例, mirrorOf指定镜像源
由于私服可以代理任何外部的仓库, 包括公共仓库, 因此可以配置使用私服作为镜像, 从而简化配置
生命周期和插件
生命周期
maven的生命周期是为了对所有的构建过程进行抽象和统一. 实际的操作由插件完成.
maven有三套独立的生命周期, clean, default, site
插件与生命周期绑定
- 插件目标
插件能完成多个功能, 每个功能就是一个插件目标, 比如complier:complie, 这是一种通用写法, 冒号前缀是插件前缀, 后缀是插件目标
- 插件绑定, 内置绑定
maven在核心的生命周期阶段绑定了很多插件的目标, 当用户通过命令行调用生命周期阶段的时候, 对应的插件目标就会执行对应的任务, 以完成实际的构建任务
default生命周期的阶段与插件目标的绑定关系由打包类型决定, 打包类型是通过pom的packaging元素定义的
自定义绑定
除了内置绑定外, 用户还能够自定义将某个插件目标绑定到生命周期的某个阶段上.
插件配置
- 命令行插件配置, -D参数键=参数值
如maven-surefire-plugin的maven.test.skip参数为true时, 会跳过执行测试
mvn install -Dmaven.test.skip=true
- POM中插件全局配置
如下, 指定了编译java1.8版本的源文件, 生成与JVM1.8兼容的字节码文件
插件仓库
插件构件同样基于坐标存储在maven仓库中
聚合和继承
依赖版本管理
这里没啥说的, 就是单体多模块工程中, 利用聚合或父子工程的继承关系进行依赖版本管理, 注意版本控制除了继承外, 也能通过import引入
插件版本管理
除了依赖能进行版本管理外, 插件也能进行版本管理, 避免重复定义
聚合和继承的关系
版本管理
版本管理是指项目整体版本的演变过程管理, 版本控制是利用版本控制工具追踪代码的每一个变更
maven版本号定义约定
比如: 1.3.4-beta-2 表示该产品的第一个重大版本的第三个次要版本的第四次增量版本的beta-2里程碑.
主干, 标签与分支
发布的版本需要打标签
灵活构建
这里讲的是可以在配置中定义变量, 然后在pom中定义