Chapter 13. Maven

13.1 Maven 概述

传统项目开发中,需要数量众多的 jar 包,需手动下载并引入,同时,jar 包有版本兼容的问题,一个 jar 包可能要依赖其他的 jar 包,需要手动解决。此外,多个项目间需要的 jar 包有可能重复。

Maven 是 Apache 软件基金会组织维护的一款自动化构建工具,专注服务于 Java 平台的项目构建和依赖管理,对生产环境下多框架、多模块整合开发有重要作用。

  • 项目设置遵循统一的规则
  • 任意工程中共享
  • 整合多个项目之间的引用关系
  • 提供规范的管理各个常用的 jar 包及其各个版本,并且可以自动下载和引入项目中
  • 能够将 jar 包所依赖的其他 jar 包自动下载并引入项目中

13.2 Maven 环境配置

首先要确保 Java 已经安装并且配好系统变量 JAVA_HOME

13.2.1 Maven 下载

下载地址:https://maven.apache.org/docs/history.html。笔者下载的是 apache-maven-3.3.9-bin.zip

下载完后,解压到自定义(不含中文)的路径,得到 Maven 的目录树如下:

1
2
3
4
5
6
7
8
9
10
11
12
apache-maven-3.3.9/
├── bin/ # 存放Maven的命令
│ ├── ...
│ └── mvn.cmd # Windows命令脚本,执行Maven的构建项目
├── boot/ # 存放一些Maven本身的引导程序,如类加载器等
├── conf/ # 存放Maven的一些配置文件
│ ├── ...
│ └── settings.xml # Maven的配置文件
├── lib/ # Maven本身运行所需的一些jar包
├── LICENSE
├── NOTICE
└── README.txt

13.2.2 设置 Maven 环境变量

新建系统变量 MAVEN_HOME,变量值为你的解压目录。

编辑系统变量 Path,添加变量值:%MAVEN_HOME%\bin

要检查 Maven 是否安装成功,在 CMD 中输入命令:mvn -v

13.3 Maven 工程

13.3.1 Maven 工程约定目录结构

1
2
3
4
5
6
7
8
9
10
11
12
你的项目/
├── src/ # 源代码
│ ├── main
│ │ ├──java # 放入项目的源码
│ │ ├──webapp # 页面素材(若是普通的JavaSE项目,无需有该目录)
│ │ └──resources # 存放项目资源文件
│ └── test
│ ├──java # 测试的源码
│ └──resources # 存放测试资源文件
├── target/ # 项目输出的位置,存放编译生成的文件
├── ...
└── pom.xml # Maven 项目核心配置文件

进入目录(当前目录有 pom.xml)后,可在CMD窗口输入 tomcat:run 命令运行 Maven 项目。根据提示信息,通过浏览器访问相应虚拟路径即可。

13.3.2 POM 文件

POM(Project Object Model,项目对象模型),是 Maven 工程的基本工作单元,是一个 XML 文件,包含了项目的基本信息,用于描述项目如何构建,声明项目依赖等。

执行任务或目录时,Maven 会在当前目录中查找 pom.xml ,读取它,获取所需的配置信息然后执行目标。

节点描述备注
modelVersion模型版本需要设置为 4.0。
groupId工程组的标识,在一个组织或项目中通常唯一。
一般是域名的倒写+项目组名,如:com.baidu.appolo
artifactId项目(模块)名称,对应 groupId
项目中的子项目
version项目的版本号(三位数字标识),若项目
还在开发中(不稳定版本),通常在版本号
中带 -SNAPSHOT
dependencies
dependency
项目有可能依赖某些 jar 包。使用该标签配置时,
而这种依赖配置正通过坐标来定位的。
依赖
properties定义一些配置属性,可设置源码编码方式
project.build.sourceEncoding)、
编译代码或运行程序所使用的JDK版本、
构建版本号(如spring.version)等
配置属性
build表示与构建相关的配置,
如设置编译插件的 JDK 版本
构建
parent多个模块需声明相同的配置,
来继承父工程的 POM 配置
继承`

groupIdartifactIdversion 这一组向量定义了一个 Maven 项目的基本坐标(gav),使得从众多 Maven 项目中可唯一定位。同时,坐标也决定了将来项目在仓库中的路径及名称。

关于 pom.xml 的更详细信息,见此教程

13.4 仓库

Maven 仓库是项目中依赖的第三方库,这个库所在的位置叫做仓库。它能够帮助我们管理构建(主要是 jar),放置所有 jar 文件(war、zip、pom 等)的地方。

Maven 仓库有以下几种类型:

13.4.1 本地仓库

Maven 的本地仓库,是在第一次执行 Maven 命令的时候才被创建。

运行 Maven 的时候,Maven 所需的任何构建优先从本地仓库寻找,若没有找到,则尝试从远程仓库下载构建至本地仓库,然后再使用本地仓库的构建。

要修改本地仓库默认位置,需在 %MAVEN_HOME%\conf 目录下的 settings.xml 文件定义另一个路径:

1
2
3
4
5
<settings xmlns="http://maven.apache.org/SETTINGS/1.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0 http://maven.apache.org/xsd/settings-1.0.0.xsd">
<localRepository>D:/maven_repository</localRepository>
</settings>

13.4.2 远程仓库

远程仓库,需通过网络才能使用,可以为多个电脑共享使用。

  • 中央仓库:由 Maven 社区提供的仓库,其中包含了绝大多数流行的开源Java构件,以及源码、作者信息、SCM、信息、许可证信息等。

  • 中央仓库的镜像::架设在不同位置,每个洲都有若干的服务器,为中央仓库分担流量。它能够减轻中央仓库的访问,下载的压力。所在洲的用户首先访问的是本洲的镜像服务器。

    配置阿里云仓库,可以在 %MAVEN_HOME%\conf\settings.xml 中的 **mirrors**节点上添加内容:

    1
    2
    3
    4
    5
    6
    <mirror>
    <id>nexus-aliyun</id>
    <mirrorOf>central</mirrorOf>
    <name>Nexus aliyun</name>
    <url>http://maven.aliyun.com/nexus/content/repositories/central</url>
    </mirror>

    详见,可参考这篇博客文章

  • 私服:在局域网环境中部署的服务器,为当前局域网范围内的所有 Maven工程服务。(公司中常使用)

13.4.3 Maven 依赖搜索顺序

当我们执行 Maven 构建命令时,Maven 开始按照以下顺序查找依赖的库:

  • 步骤 1 - 在本地仓库中搜索,如果找不到,执行步骤 2,如果找到了则执行其他操作。
  • 步骤 2 - 在中央仓库中搜索,如果找不到,并且有一个或多个远程仓库已经设置,则执行步骤 4,如果找到了则下载到本地仓库中以备将来引用。
  • 步骤 3 - 如果远程仓库没有被设置,Maven 将简单的停滞处理并抛出错误(无法找到依赖的文件)。
  • 步骤 4 - 在一个或多个远程仓库中搜索依赖的文件,如果找到则下载到本地仓库以备将来引用,否则 Maven 将停止处理并抛出错误(无法找到依赖的文件)。

13.5 Maven 指令的生命周期

Maven 常用命令

以下命令,必须在命令行进入 pom.xml 所在目录时,方能执行。

  • mvn clean:清理 (会删除原来编译和测试的目录,即 target目录,但是已经 install到仓库里的包不会删除 )
  • mvn compile:编译主程序 (会在当前目录下生成一个 target,里边存放编译主程序之后生成的字节码文件 )
  • mvn test compile:编译测试程序 (会在当前目录下生成一个 target,里边存放编译测试程序之后生成的字节码文件 )
  • mvn test:测试 (会生成一个目录 surefire-reports,保存测试结果 )
  • mvn package:打包主程序 (会编译、编译测试、测试、并且按照 pom.xml 配置把主程序打包生成 jar 包或者 war 包 )
  • mvn install:安装主程序 (会把本工程打包,并且按照本工程的坐标保存到本地仓库中 )
  • mvn deploy:部署主程序 (会把本工程打包,按照本工程的坐标保存到本地库中,并且还会保存到私服仓库中。
    还会自动把项目部署到 web 容器中 )。

Maven 对项目构建过程分为三套相互独立的生命周期:

  • Clean Lifecycle:在进行真正的构建之前进行一些清理工作

  • Default Lifecycle:构建的核心部分,编译,测试,打包,部署等

    阶段处理描述
    验证 validate验证项目验证项目是否正确且所有必须信息是可用的
    编译 compile执行编译源代码编译在此阶段完成
    测试 Test测试使用适当的单元测试框架(例如JUnit)运行测试。
    包装 package打包创建JAR/WAR包如在 pom.xml 中定义提及的包
    检查 verify检查对集成测试的结果进行检查,以保证质量达标
    安装 install安装安装打包的项目到本地仓库,以供其他项目使用
    部署 deploy部署拷贝最终的工程包到远程仓库中,以共享给其他开发人员和工程
  • Site Lifecycle:生成项目报告,站点,发布站点。

在 IDEA 中右侧的 Maven 窗口,可直接点击相关指令

13.6 依赖

13.6.1 引入依赖

MVNREPOSITORY 中搜索你需要的 jar ,复制其坐标(groupIdartifactIdversion 等),到 %MAVEN_HOME%\conf\settings.xml 中的 **dependencies**节点上。

比如说:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.servlet.jsp</groupId>
<artifactId>jsp-api</artifactId>
<version>2.1</version>
<scope>provided</scope>
</dependency>
</dependencies>

13.6.2 依赖范围

依赖的范围:compiletestprovided,默认为 compile

compiletestprovided
对主程序是否有效✔️✔️
对测试程序是否有效✔️✔️✔️
是否参与打包✔️
是否参与部署✔️

13.7 Maven 在 IDEA 中的应用

13.7.1 IDEA的 Maven 配置

配置当前工程的设置

在 File -> Settings -> Build,Execution,Deployment 中,设置如下:

参数描述
Maven home directoryMaven的安装目录
User settings fileMaven安装目录下的 conf/setting.xml 配置文件
Local repository本机仓库的目录位置

此外,在 Runner 中设置 VM Options(默认情况下,Maven 项目创建时,会联网下载模板文件):-DarchetypeCatalog=internal

配置以后新建工程的设置

13.7.2 使用模板创建 Java 工程

选择:maven-archetype-quickstart

创建时,可对 GroupIdArtifactIdVersion 进行自定义设置。

模板创建的目录结构不完整,需手动补齐并添加

13.7.3 使用模板创建 Web 工程

选择:maven-archetype-webapp

更改web.xml头文件版本号

注意,IDEA创建 Maven 项目时,注意要修改 web.xml 头文件版本为4.0:

打开项目结构,然后如图修改 Web:

对新创建的 web.xml 随便取个名(为了触发内容的更改),点击确定得到该文件后再重命名为 web.xml 即可。

若要更改默认的版本,具体方法参考此篇文章

13.7.4 重新加载依赖