@TOC
一、什么是Maven
Maven 是一种用来管理 Java 项目的工具,但不是那种用来管理资源规划和调度的工具。它处理的是管理一个具体的项目所涉及的各种任务,如编译、测试、打包、文档以及分发。
1.1 Maven的组成
Maven 包括以下的几个部分。
- 一组用于处理依赖管理、目录结构以及构建工作流的约定。基于这些约定实现的标准化可以极大地简化开发过程。例如,一个常用的目录结构使得开发者可以更加容易地跟上不熟悉的项目的节奏。
- 一个用于项目配置的XML Schema:项目对象模型(Project Object Model),简称POM。每一个Maven项目都拥有一个POM文件 。
- 一个委托外部组件来执行项目任务的插件架构。这简化了更新以及扩展 Maven 能力的过程。
1.2 安装和配置Maven
1.2.1 下载
可以从此处下载适合于你的系统的Maven tar.gz或者zip文件。
1.2.2 安装
安装非常简单:将下载内容解压到你选择的任意文件夹(我们称之为<安装目录>)中。
下来我们以apache-maven-3.8.6举例:
第一步: 将环境变量 M2_HOME 设置为指向<安装目录>apache-maven-3.8.6,这个环境变量将会告诉 Maven 在哪里能找到它的配置文件,conf\settings.xml;
第二步:将%M2_HOME%\bin(在 Linux 上是${M2_HOME}/bin)添加到你的执行路径,在这之后,在命令行执行 mvn 就能运行 Maven 了。
在编译和运行示例项目时,不需要修改默认配置。在首次执行mvn时,Maven会为你创建本地存储库,并从Maven中央存储库下载基本操作所需的大量JAR文件。最后,它会下载构建当前项目所需要的依赖项。settings.xml的详细信息可以在找到。
二、Maven 的基本概念
2.1 标准的目录结构
Maven定义了一个标准的项目目录结构 。(注意:并不是每种类型的项目都需要Maven的所有元素,很多都可以在必要的时候在POM文件中重写。)
2.2 POM 大纲
2.2.1 pom大纲展示
<project> //根元素
<groupId/>
<artifactId/> //唯一地定义一个Maven 项目的值
<version/>
<packaging/> //该项目所产生的构件的类型;默认值是 jar
<properties/> //在 POM 中所引用的符号
<dependencies/> //构建当前项目所需要的其他 Maven 项目
<build/> //构建该项目所需要执行的任务的配置
<profiles/> //为不同的用例自定义POM的命名的配置
</project>
2.3 构件
2.3.1 什么是maven的构建
任何可以被 Maven 的坐标系统唯一标识的对象都一个 Maven 构件。大多数情况下,构件是构建 Maven 项目所生成的文件,如 JAR。但是,只包含其他 POM(该文件本身并不产生构件)使用的定义的 POM 文件也是 Maven 构件。Maven 构件的类型由其 POM 文件的元素指定。最常用的值是 pom、jar、ear、war 以及 maven-plugin。
2.4 POM 文件的用例
可以通过以下的方式来使用 POM 文件。
- 默认的——用于构建一个构件。
- 父 POM——提供一个由子项目继承的单个配置信息源——声明这个 POM 文件作为它们
的元素的值。 - 聚合器——用于构建一组声明为的项目,这些子项目位于其当前聚合器项目的文件夹中,每个都包含有它自己的 POM 文件。
作为父 POM 或者聚合器的 POM 文件的元素的值将是 pom。注意,一个 POM文件可能同时提供两项功能。
2.5 GAV 坐标
POM 定义了 5 种称为坐标的元素,用于标识 Maven 构件。首字母缩写 GAV 指的是必须始终指定的 3 个坐标、以及的首字母。
下面的坐标是按照它们在坐标表达式中出现的顺序列出的。
1、groupId : 是项目或者项目组的全局的唯一标识符。这通常是 Java 源代码中使用的全限定的 Java 包名。例如,io.netty、com.google。
2、artifactId: 用于标识和某个相关的不同的构件。例如,netty-all、netty-handler。
3、type: 是指和项目相关的主要构件的类型(对应于构件的 POM 文件中的值)。它的默认值是 jar。例如,pom、war、ear。
5、version: 标识了构件的版本。例如,1.1、2.0-SNAPSHOT、、4.1.9.Final。
6、classifier: >用于区分属于相同的 POM 但是却被以不同的方式构建的构件。例如,javadoc、sources、jdk16、jdk17。
例如:
- 完整的坐标表达式具有的格式:artifactId:groupId:packaging:version:classifier
- 包含 Netty 的所有组件的GAV 坐标:io.netty:netty-all:4.1.9.Final
- POM 文件必须声明它所管理的构件的坐标。上面的组件具有如下坐标的项目:
<groupId>io.netty</groupId>
<artifactId>netty-all</artifactId>
<version>4.1.92.Final</version>
<packaging>jar</packaging>
- 它的的构件具有以下格式的名称:artifactId-version.packaging
- 在这种情况下,它将产生这个构件:netty-all-4.1.9.Final.jar
三、依赖
项目的依赖是指编译和执行它所需要的外部构件。在大多数情况下,项目的依赖项也会有它自己的依赖。我们称这些依赖为你的项目的传递依赖。一个复杂的项目可能会有一个深层级的依赖树;
Maven提供了各种用于帮助理解和管理它的工具。Maven的声明在POM的元素中:
<dependencies>
<dependency>
<groupId/>
<artifactId/>
<version/>
<type/>
<scope/>
<systemPath/>
</dependency>
...
</dependencies>
在声明中,GAV坐标总是必不可少的。。type以及scope元素对于那些值不分别是默认值jar和compile的依赖来说也是必需的。
举个例子:
<dependencies>
<dependency>
<groupId>io.netty</groupId>
<artifactId>netty-all</artifactId>
<version>4.1.92.Final</version>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
<version>${
junit.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-engine</artifactId>
<version>${
junit.version}</version>
<scope>test</scope>
</dependency>
</dependencies>
元素可以具有以下值。
- compile—编译和执行需要的(默认值)。
- runtime—只有执行需要。
- optional——不被引用了这个项目所产生的构件的其他项目,视为传递依赖。
- provided——不会被包含在由这个 POM 产生的 WAR 文件的 WEB_INF/lib 目录中。
- test——只有编译和测试的执行需要。
- import——这将在后面的“依赖管理”一节进行讨论。
- systemPath元素用来指定文件系统中的绝对位置。
Maven 用来管理项目依赖的方式,包括了一个用来存储和获取这些依赖的存储库协议,已经彻底地改变了在项目之间共享 JAR 文件的方式,从而有效地消除了项目的中每个开发人员都维护一个私有 lib 目录时经常会出现的问题。