引言
很多JAVA程序员对Maven
,似乎很熟,但又好像不熟;
为什么这么说呢?
原因很简单,要说不熟吧,偏偏每天都有所接触;要说熟吧,可是对许多高级功能又仅是一知半解。
一、Maven的介绍和入门
官网:Maven – Welcome to Apache Maven
Maven
是专门用于构建、管理Java
项目的工具,它为我们提供了标准化的项目结构,如下:
├─ProjectName // 项目名称 │ ├─src // 根目录 │ │ ├─main // 主目录 │ │ │ ├─java // Java源码目录 │ │ │ ├─resources // 配置文件目录 │ │ │ └─webapp // Web文件目录 │ │ ├─test // 测试目录 │ │ │ ├─java // Java测试代码目录 │ │ │ └─resources // 测试资源目录 │ └─pom.xml // Maven项目核心配置文件
同时也提供了一套标准的构建流程:
从编译,到测试、打包、发布……,涵盖整个项目开发的全流程。
并且最重要的一点,它还提供了依赖(Jar
包)管理功能,回想大家最初学JavaEE
时,想要用到一个外部的工具包,必须先从网上找到对应的Jar
文件,接着将其手动丢到项目的lib
目录下,当项目需要依赖的外部包达到几十个、每个外部包还依赖其他包时,这个过程无疑很痛苦。
而这一切的一切,随着Maven
的出现,从此不复存在。
1.1、Maven安装指南
使用Maven
前,必须先安装它,这时可以先去到官网下载自己所需的版本:
下载进行解压后(不过解压的目录最好别带中文,否则后续会碰到一些问题),接着需要配置一下,总共分为四步。
①在系统环境中,新建一个MAVEN_HOME
或M2_HOME
的环境变量,值写成解压路径。
②找到Path
变量并编辑,在其中新增一行,配置一下bin
目录:%M2_HOME%\bin。
③找到Maven
解压目录下的conf/settings.xml
,然后点击编辑,找到<localRepository>
标签,将其挪动到注释区域外,然后配置本地仓库位置:<localRepository>本地目录</localRepository>
④由于Apache
的官方镜像位于国外,平时拉取依赖比较慢,所以还需配置Maven
国内的镜像源,这时在settings.xml
文件中,先搜索<mirrors>
标签,接着在其中配置阿里云的镜像地址:
<mirror>
<id>alimaven</id>
<name>aliyun maven</name>
<url>http://maven.aliyun.com/nexus/content/groups/public/</url>
<mirrorOf>central</mirrorOf>
</mirror>
最后在终端工具,执行mvn -v
命令检测一下。
到这里,整个Maven
安装流程全部结束。
1.2、Maven入门指南
IDEA
创建Maven
项目,不过要记得配置一下本地Maven
及仓库位置:
1.2.1 IDEA创建Maven项目
接着就可以创建Maven
项目,这个过程特别简单,先选择New Project
:
这里选创建springboot--Maven
项目,接着指定一下JDK
这里需要写一下GAV
坐标,稍微解释一下三个选项的含义:
GroupID
:组织ID
,一般写公司的名称缩写;ArtifactID
:当前Maven
工程的项目名字;Version
:当前Maven
工程的版本。
这一步结束后,就得到了一个springboot的Maven
项目,然后可以基于Maven
实现依赖管理。
1.2.2 Maven依赖管理
最简单的依赖管理,总共就只有三步,如下:
- ①在
pom.xml
中,先写一个<dependencies>
标签; - ②在
<dependencies>
标签中,使用<dependency>
标签来导入依赖; - ③在
<dependency>
标签中,通过GAV
坐标来导入依赖。
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<version>3.1.0</version>
</dependency>
如果你不知道一个依赖的GAV坐标
该怎么写,可以去仓库:https://mvnrepository.com/中搜索;
引入新的GAV
坐标后,依赖不会立马生效,需要手动刷新一下项目:
IDEA
自带的Maven
项目工具来进行刷新
1.2.3 依赖范围管理
在软件开发的过程中,通常会使用第三方库或框架来提高开发的效率和质量。有时候,这些依赖可能只需要在特定的环境中使用,比如开发和测试环境,而在生产环境中并不需要。针对这种情况,可以通过Maven的<scope>
标签来控制这些依赖的生效范围。
其中,<scope>
标签有以下几个可选值:
compile
:默认的 scope,依赖会在所有阶段都可用;provided
:依赖不会打包到 JAR 文件中,在编译和测试阶段可用,但在运行时不可用;runtime
:依赖不会在编译时使用,但会在运行时和测试阶段使用;test
:依赖只在测试阶段使用,在编译和运行时都不使用;system
:类似于provided
,但需要指定依赖的jar
文件路径。
以测试依赖为例,可以在 Maven 的 POM 文件中使用 test
来使得这些依赖只在测试环境中生效,而不会打包到最终的应用程序中。例如,对于 测试包,可以这样配置:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
这表示 依赖只在测试阶段中生效,而在编译和运行时不会被包含在最终的应用程序中。您也可以使用其他可选的 scope 值来控制其他依赖的生效范围。
请注意,使用<scope>
标签来指定依赖生效的范围只是一种约束,并不是完全禁止依赖包的使用。因此建议不要在应用程序中使用测试依赖和其他不必要的依赖,以保持应用程序的简洁性和安全性。
同时,<scope>
标签还可以通过自定义的方式来添加其他的scope
范围,例如Maven
插件中使用的scope
值:
<dependencies>
<dependency>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.0</version>
<scope>plugin</scope>
</dependency>
</dependencies>
这里使用了 <scope>plugin</scope>
来指定 maven-compiler-plugin
的依赖范围,使其只在构建阶段生效。如果省略 <scope>
元素,Maven 会默认将其解释为 compile
范围,即依赖会在所有阶段都可用。
需要注意的是,插件依赖的版本号通常由插件本身指定,因此在声明插件依赖的时候不需要指定版本号。Maven 会自动解析插件依赖的版本,并使用插件本身所在的版本来进行构建过程中需要执行的任务。
1.3 Maven工作原理
在 Maven 中,项目能够依赖于其他项目或库,而这些依赖项通常存储在仓库(Repository)中。Maven 有两种类型的仓库:本地仓库和远程仓库。
本地仓库是一个位于本地计算机上的仓库,用于存储本地项目和远程仓库下载的依赖项。默认情况下,本地仓库位于用户目录下的 .m2/repository
目录中。
远程仓库是网络上的一个公共仓库,用于向 Maven 提供者们公开他们的软件包。Maven 在运行时从远程仓库中下载所需的依赖项,并将它们存储在本地仓库中。Maven 默认使用 Maven Central 作为默认的远程仓库。
工程是 Maven POM 文件的一部分,它提供了项目的构建和描述信息。POM 通过依赖声明来指定项目依赖项及其版本信息。当 Maven 构建项目时,会解析 POM 文件并从本地或远程仓库下载所需的依赖项,以完成项目构建过程。
因此,在 Maven 中,POM 节点既可以是“依赖使用者”,也可以是“依赖提供者”。如果一个项目 A 依赖于项目 B,则项目 A 是“依赖使用者”,而项目 B 是“依赖提供者”。Maven 会通过 POM 文件中的依赖声明来维护这两种节点之间的关系。
看着或许有点头大,要讲明白得先弄清里面三种仓库:
- 中央仓库:就是前面配置的镜像源,里面拥有海量的公共
jar
包资源; - 远程仓库:也叫私服仓库,主要存储公司内部的
jar
包资源,这个后续会细说; - 本地仓库:自己电脑本地的仓库,会在磁盘上存储
jar
包资源。
大致了解三种仓库的含义后,接着来梳理Maven
的工作流程:
- ①项目通过
GAV
坐标引入依赖,首先会去本地仓库查找jar
包; - ②如果在本地仓库中找到了,直接把依赖载入到当前工程的
External Libraries
中; - ③如果没找到,则去读取
settings.xml
文件,判断是否存在私服配置; - ④如果有私服配置,根据配置的地址找到远程仓库,接着拉取依赖到本地仓库;
- ⑤如果远程仓库中没有依赖,根据私服配置去中央仓库拉取,然后放到私服、本地仓库;
- ⑥从远程或中央仓库中,把依赖下载到本地后,再重复第二步,把依赖载入到项目中。
上述六步便是Maven
的完整工作流程,可能许多人没接触过私服,这个会放到后面聊。如果你的项目没配置Maven
私服,那么第三步时,会直接从settings.xml
读取镜像源配置,直接去到中央仓库拉取依赖。
在 Maven 中,本地仓库和远程仓库都遵循统一的构建规范,并且可以通过 GAV 坐标(groupId、artifactId 和 version)来标识和定位依赖项。只要在项目中正确书写了依赖项的 GAV 坐标信息,Maven 就能够自动查找并下载所需的依赖项,并将其载入到项目中。
1.4 Maven 生命周期
Maven 生命周期中包含三个关键的概念:阶段(phase)、目标(goal)和插件(plugin)。
Maven 生命周期总共分为三个阶段:clean、default 和 site。每个阶段都由一组阶段(phase)组成,阶段则由一个或多个插件目标(goal)构成。
- clean 阶段:清理项目工作目录,删除之前构建生成的文件。包括 pre-clean、clean 和 post-clean 三个阶段。
- default 阶段:构建项目的主要阶段,包括编译、打包、测试、部署等操作。包括 validate、compile、test、package、verify、install 和 deploy 七个阶段。
- site 阶段:生成项目的站点文档。包括 pre-site、site 和 post-site 三个阶段。
clean:清除当前工程编译后生成的文件(即删除target整个目录); validate:对工程进行基础验证,如工程结构、pom、资源文件等是否正确; compile:对src/main/java目录下的源码进行编译(会生成target目录); test:编译并执行src/test/java/目录下的所有测试用例; package:将当前项目打包,普通项目打jar包,webapp项目打war包; verify:验证工程所有代码、配置进行是否正确,如类中代码的语法检测等; install:将当前工程打包,然后安装到本地仓库,别人可通过GAV导入; site:生成项目的概述、源码测试覆盖率、开发者列表等站点文档(需要额外配置); deploy:将当前工程对应的包,上传到远程仓库,提供给他人使用(私服会用)。
上述便是九个周期阶段命令的释义,而Maven
总共划分了三套生命周期: