1. Maven简介

1.1 概念

Maven 是 apache 基金会的开源项目,使用 Java 语法开发。Maven 是项目的自动化构建工具,可以管理项目的依赖。

1.2 作用

1.2.1 自动构建

可以帮助开发人员做项目代码的编译、测试、打包、安装、部署等工作

1.2.2 管理依赖

管理项目中的各种 jar 包。若没有 Maven,我们需要自己找到需要的 jar 包,然后导入到项目中,有了 Maven 之后,只需要导入依赖即可。

1.3 安装

安装并配置 Maven 的前提是 JDK 相关的配置已经配好了,也就是 ​​JAVA_HOME​​ 和 ​​Path​​ 中都进行了相应的配置

参照官方文档,主要是需要配置环境变量,跟配置 JDK 环境变量差不多:

  • 配置系统变量:变量名是 ​​MAVEN_HOME​​,变量值是 ​​D:\apache-maven-3.6.3​
  • 配置环境变量:在 ​​Path​​ 中添加 ​​%MAVEN_HOME%\bin​

配置好之后,在 cmd 命令行窗口执行 ​​mvn -version​​ 查看是否安装成功

1.4 配置文件

在安装目录下的 ​​conf​​ 文件夹下有一个 ​​setting.xml​​ 配置文件,在其中做一些配置

1.4.1 更改默认本地仓库地址

我们使用 Maven 引入依赖时,会先在本地仓库查找,有的话直接引入;没有的话会下载到本地仓库再引入。

  
<!-- localRepository
| The path to the local repository maven will use to store artifacts.
|
| Default: ${user.home}/.m2/repository
<localRepository>/path/to/local/repo</localRepository>
-->
<!-- 可以看到注释中默认的仓库地址是C盘中用户目录下的.m2/repository,可以通过如下方式自定义目录 -->
<localRepository>G:/LocalRepository</localRepository>


1.4.2 配置中心仓库镜像下载源

<mirror>      
<id>nexus-aliyun</id>
<mirrorOf>central</mirrorOf>
<name>Nexus aliyun</name>
<url>http://maven.aliyun.com/nexus/content/groups/public</url>
</mirror>


1.4.3 配置Java版本

<!-- 指定 Java 版本,使得这里的版本跟项目中使用的 Java 版本一致 -->
<profile>
<id>jdk-1.8</id>
<activation>
<activeByDefault>true</activeByDefault>
<jdk>1.8</jdk>
</activation>
<properties>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
<maven.compiler.compilerVersion>1.8</maven.compiler.compilerVersion>
</properties>
</profile>


2. Maven的核心概念

2.1 Maven项目的目录结构

myapp项目文件夹
\src
\main 主程序目录(完成项目功能的代码和配置文件)
\java 源代码(包和相关的类定义)
\resources 资源文件
\test 测试程序代码目录(开发人员自己写的测试代码)
\java 测试代码(junit)
\resources 测试程序需要的资源文件
\pom.xml 该项目的maven配置文件,核心文件


2.2 pom.xml

POM:Project Object Model 项目对象模型,Maven 把项目当做模型处理,操作这个模型就是操作项目。

Maven 通过 pom.xml 文件实现项目的构建和依赖的管理。

<?xml version="1.0" encoding="UTF-8"?>

<!-- project 是根标签,后面的是约束文件 -->
<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 模型的版本 -->
<modelVersion>4.0.0</modelVersion>

<!-- 坐标 -->
<groupId>com.mycompany.app</groupId>
<artifactId>my-app</artifactId>
<version>1.0-SNAPSHOT</version>

<properties>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
</properties>

<!-- 依赖 -->
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
</dependencies>
</project>


2.2.1 坐标

坐标由 groupId、artifiactId、version(GAV)三部分组成,是资源的唯一标识(确定资源唯一性),在 Maven 中,每个资源都对应唯一的坐标

使用其他 jar 包就是在依赖 ​​<dependency>​​ 中通过坐标来引入

<groupId>com.mycompany.app</groupId>
<artifactId>my-app</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>jar</packaging>

<!--
groupId: 项目组织的唯一标识符,这个值常使用的公司域名的倒写。例如 com.dxx
如果项目规模比较大, 也可以是 域名倒写 + 大项目名称。例如 com.dxx.bigdemo

artifactId:项目的唯一标识符,如果 groupId 中有项目,此时当前的值就是子项目名

version:项目的版本号,一般由三位数字组成:主版本号.次版本号.小版本号。例如:5.2.3
SNAPSHOT意为快照,说明该项目还处于开发中,是不稳定的版本

packaging:项目打包的类型,有 jar ,war, ear, pom 等,默认是jar
-->


2.2.2 依赖

Maven 项目通过依赖来导入需要使用的资源,也就是 jar 包

依赖的使用方式:在 ​​<dependency>​​ 标签中引入 GAV,GAV 可以在 Maven 官方地址中搜索

<dependencies>

<!-- 日志 -->
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>

<!-- mysql驱动 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.16</version>
</dependency>

</dependencies>


2.3 仓库

Maven 仓库是用来存放 jar 包的,仓库分为三类:

  1. 本地仓库,也就是本机中的仓库,在 1.4 中我们进行过默认本地仓库地址的修改
  2. 远程仓库,也就是需要联机进行访问的仓库,在 1.4 中我们配置过远程仓库的镜像。一般在公司中会有局域网远程仓库,供公司内部使用

2.4 生命周期

Maven 的生命周期就是对所有的构建过程进行抽象和统一。包含了项目的清理、初始化、编译、测试、打包、集成测试、验证、部署和站点生成等几乎所有的构建步骤。

Maven 的生命周期是抽象的,即生命周期不做任何实际的工作,实际任务由 插件 完成,类似于设计模式中的模板方法。

Maven 有三个标准的生命周期,分别是 clean、default 和 site

2.4.1 clean

清理项目,包含三个阶段:

  • pre-clean:执行清理前需要完成的工作
  • clean:清理上一次构建生成的文件
  • post-clean:执行清理后需要完成的工作

2.4.2 default(build)

构建项目,包含的阶段如下:

  • validate:验证工程是否正确,所有需要的资源是否可用
  • compile:编译项目的源代码
  • test:使用合适的单元测试框架来测试已编译的源代码。这些测试不需要已打包和布署
  • Package:把已编译的代码打包成可发布的格式,比如 jar
  • integration-test:如有需要,将包处理和发布到一个能够进行集成测试的环境
  • verify:运行所有检查,验证包是否有效且达到质量标准
  • install:把包安装到 maven 本地仓库,可以被其他工程作为依赖来使用
  • Deploy:在集成或者发布环境下执行,将最终版本的包拷贝到远程的 repository,使得其他的开发者或者工程可以共享

2.4.3 site

建立和发布项目站点,包含阶段如下:

  • pre-site:生成项目站点之前需要完成的工作
  • site:生成项目站点文档
  • post-site:生成项目站点之后需要完成的工作
  • site-deploy:将项目站点发布到服务器

2.5 插件和命令

使用命令来构建项目的生命周期,而执行命令的功能是通过插件完成的。插件就是一些 jar 包、类等等。

2.5.1 常用命令

  • mvn clean:调用 clean 生命周期的 clean 阶段,实际执行 clean 及之前所有阶段
    作用是删除以前生成的数据,删除target目录,使用的插件是 maven-clean-plugin
  • mvn compile:调用 clean 生命周期的 compile 阶段,实际执行 compile 及之前所有阶段
    作用是将源代码目录下的 .java 文件编译成 .class 文件,并将 class 文件放在 target/classes 目录
  • mvn test-compile:同上
    将测试目录下的 .java 文件编译成 .class 文件,并将 class 文件放在 target/test-classes 目录
  • mvn test:同上
    执行 test-classes 目录下的程序
  • mvn package:同上
    把项目中的资源 class 文件和配置文件都放到一个压缩文件中, 默认压缩文件是 jar 类型
  • mvn install:同上
    把生成的打包文件安装到 Maven 仓库
  • mvn clean package:组合命令,先 clean,再 package

2.5.2 自定义插件的配置

在 pom.xml 文件中的 ​​<build>​​ 标签中进行插件的配置

<!-- 设置构建项目相关的内容 -->
<!-- 此配置跟我们在 1.4.3 中实现的效果是一样的,此配置针对这个项目,1.4.3 中的配置针对所有 Maven 项目 -->
<build>
<plugins>
<!-- 设置插件 -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<configuration>
<source>1.8</source> <!-- 指定编译代码的jdk版本 -->
<target>1.8</target> <!-- 运行java程序使用的jdk版本 -->
</configuration>
</plugin>
</plugins>
</build>


3. 在IDEA中使用Maven

3.1 进行设置

IDEA 中有自带的 Maven,我们通过更改设置使用自己安装的 Maven,如下图所示:

Maven的简单使用_jar

分别配置 Maven 安装目录、配置文件目录、本地仓库目录。

注意:上述设置仅针对当前项目有效,若想让新项目也使用这些设置,需要在 Other Setting 中为新项目进行设置

3.2 使用

新建 Maven 项目即可,有一些 archetype 可供选择,最常用的就是 webapp,Maven 会自动帮我们构建好项目结构并创建必备的文件。

当然也可以创建一个空的 Maven 项目,之后自己手动创建需要的东西。

双击 IDEA 中的 Maven 窗口中的生命周期下的命令,就相当于在命令行窗口执行相应的命令。

Maven的简单使用_xml_02

3.3 普通项目转成Maven项目

在项目名称上右键,点击 ​​Add Framework Support​​,选择 Maven 即可。

4. 依赖管理

4.1 依赖范围

​<scope>​​ 标签:表示依赖的范围,也就是设置此依赖在项目的哪个阶段起作用

​<scope>​​ 的常用值如下:

  • compile:默认值,表示此依赖需要参与当前项目的编译
  • test:表示此依赖仅仅参与测试相关的工作,比如 Junit
  • provided:表示打包时此依赖不需要打包进去,由服务器提供这个依赖。相当于 compile 在打包阶段做了 exclude 的动作

4.2 依赖冲突

所谓的依赖冲突,就是项目依赖的一些 jar 包(假定为 target 包),由于项目有很多依赖,部分依赖(比如 A 和 B)依赖了不同版本的 target,就造成了版本冲突。

依赖冲突经常是类包之间的间接依赖引起的。每个显式声明的类包都会依赖于一些其它的隐式类包,这些隐式的类包会被间接引入进来,从而造成类包冲突

4.2.1 分析

有两种分析方法:

  • 使用命令行
    mvn -Dverbose dependency:tree
  • 使用插件
    在 IDEA 中安装 Maven Helper 插件

4.2.2 解决

一般会优先使用高版本的依赖

  • 第一声明优先原则
    自上而下,使用先声明的依赖的传递依赖
  • 路径近者优先原则
    直接依赖优于传递依赖
  • 排除依赖
    将冲突的依赖使用 <exclusion> 排除掉
  • 版本锁定
    使用 <dependencyManager> 锁定冲突的依赖的版本号

5. pom.xml常用配置

5.1 properties配置

<properties>
<maven.compiler.source>1.8</maven.compiler.source> <!-- 源码编译 jdk 版本 -->
<maven.compiler.target>1.8</maven.compiler.target> <!-- 运行代码的 jdk 版本 -->
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <!-- 项目构建使用的编码,避免中文乱码 -->
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <!-- 生成报告的编码 -->
</properties>


5.2 全局变量

在 ​​<properties>​​ 中自定义标签,这个标签就是一个全局变量,标签的文本就是变量的值。类似于 Java 中的全局静态常量

多个依赖使用相同的版本号时,就可以使用全局变量

<properties>
...
<!--自定义变量-->
<spring.version>5.2.5.RELEASE</spring.version>
</properties>

<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>${spring.version}</version> <!-- 使用变量 -->
</dependency>

<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>${spring.version}</version> <!-- 使用变量 -->
</dependency>