[Buy Me a Java] Maven 快速上手指南
Maven 是一个项目管理工具,可以通过配置文件(pom.xml)来管理项目的构建、报告和文档。
参考资料:
https://www.bilibili.com/video/BV1uApMeWErY
https://www.nosuchfield.com/2023/06/16/Maven-Details/
Maven 的生命周期
Maven 使用生命周期(lifecycle)表示软件开发和构建的流程,并总结出了三套默认的生命周期。
- clean:清理项目
- default:构建项目
- site:构建项目站点
每个生命周期内又由多个阶段(phase)组成。phase 的执行有先后顺序的概念。在执行某个 phase 时,会按顺序从这个 lifecycle 最开始的 phase 开始执行,当上一个 phase 执行完成后会开始继续执行下一个 phase,一直执行到当前指定的 phase 结束。
这里关注几个常用的 phase。
default 的阶段 | 用途 |
---|---|
compile | 编译项目主源码,编译 src/main/java 目录内的 Java 文件到输出主 classpath 目录,如 idea 中生成的 target 文件夹 |
test | 执行单元测试 |
package | 将编译好的代码打包成可发布的格式,如 jar |
install | 将打包好的文件安装到本地仓库 |
deploy | 将打包好的文件发布到远程仓库 |
简单来说就是 编译 -> 测试 -> 打包 -> 安装 | 发布
这一套流程。
如果是在 idea 中,点击右侧
M
按钮,点击Lifecycle
即可看到相关选项。或者在命令行中执行相关命令可以得到同样效果。
配置文件 pom.xml
这是一个新建的 maven 项目的配置文件 pom.xml,POM 是 Project Object Model 的缩写,翻译过来就是项目对象模型。
<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">
<modelVersion>4.0.0</modelVersion>
<groupId>com.insorker</groupId>
<artifactId>maven-test</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>jar</packaging>
<name>maven-test</name>
<url>http://maven.apache.org</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>
</dependencies>
</project>
项目相关的配置如下
元素 | 含义 |
---|---|
groupId | 项目所属的组织或公司名 |
artifactId | 项目名 |
version | 项目的版本 |
name | 项目的可读名称,非必须 |
description | 项目的描述,非必须 |
packaging | 项目的打包方式,非必须,默认为 jar |
<properties>
标签可以定义一些常量,比如定义某个通用的版本号,避免后续修改版本号时重复修改多次。
<properties>
<mybatis.spring>2.2.0</mybatis.spring>
</properties>
<dependencies>
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>${mybatis.spring}</version>
</dependency>
...
</dependencies>
<dependencies>
标签定义了项目相关的依赖,其中某个具体的依赖包裹在 <dependency>
标签中。相关的元素含义基本同上所述,这里详细描述一下新增的 scope
。
scope 表示依赖的作用范围,分为 test、compile、provided 和 runtime。即依赖产生作用的不同的 classpath。
scope | 含义 |
---|---|
compile | 如果不指定就使用 compile 选项,代表编译依赖范围。使用这个配置的依赖范围的 maven 依赖,在编译、测试和运行的时候这个依赖都有效。例如 spring-code。 |
test | 依赖指对测试文件生效,如,junit 在 src 文件夹中不能 import。 |
provided | 依赖对编译和测试 classpath 有效,对运行时 classpath 无效。例如 servlet-api,运行时 tomcat 会提供。 |
runtime | 运行时依赖范围,对测试和运行 classpath 有效,对编译时无效。例如 JDBC 驱动,代码编译的时候只需要接口,实现只在真正运行时才需要。即 SPI(Service Provider Interface)机制下常用。 |
仓库 & 坐标
Maven 通过仓库管理 jar 包,方便项目的下载或引用。共有三种仓库,分别是本地仓库、私服仓库和中央仓库。
一般项目依赖会从中央仓库进行下载,如果配置了私服仓库则会从私服仓库下载。下载好的依赖会存储在本地仓库中,本地仓库是电脑上的一个目录,项目使用的依赖可以从对应的路径找到对应的 jar 包。
配置文件 pom.xml 这一节中已经提到过了 groupId
、artifactId
和 version
这三个概念。通过这三个信息就如同 3 维坐标轴一样确定了一个唯一对应的依赖。
通过中央仓库,即 https://mvnrepository.com/ ,从中找到具体的依赖,选中某个版本(可以参考右侧的选择率),复制代码添加到 pom.xml 中即可添加依赖。
依赖冲突
在 idea 中查看依赖,可以发现某个依赖 A 可能依赖了某个依赖 B,依赖 C 也同时依赖了依赖 B,但是版本不同,这就产生了依赖冲突。但是不必担心,maven 会自动选择某个依赖,选择顺序为
- 最短路径:路径最短,深度最浅的依赖优先选择
- 顺序选择:按从上到下的顺序选择依赖
当然也可以手动选择依赖的版本。具体方法可以通过添加 <exclusion>
标签或 <optional>
标签实现,这里不再赘述。
父子工程
Maven 完全支持多级的父子工程结构。父项目通过 <modules>
标签管理子模块,如
<modules>
<module>m-a</module>
<module>m-b</module>
<module>m-c</module>
</modules>
子项目通过 <parent>
标签从父项目继承配置。
<parent>
<groupId>com.insorker</groupId>
<artifactId>maven-test</artifactId>
<version>1.0-SNAPSHOT</version>
</parent>
默认继承所有 <dependencies>
中 <scope>
为 compile 的依赖,但是一般为了方便管理,在父项目的配置文件中使用 <dependencyManagement>
标签管理,这样子模块可以通过配置指定具体继承的依赖,配置时无需指明版本号。