实战讲解Maven安装及基本使用详解
庄周de蝴蝶 人气:0前言
Apache Maven
,是一个跨平台的软件项目管理及自动构建工具,由Apache软件基金会所提供。Maven
主要服务于基于Java
平台的项目构建、依赖管理和项目信息管理。Maven
的目标是能够让开发者在最短的时间内了解项目开发工作的完整状态,主要包括以下几个方面:
•简化项目构建过程
•提供一个统一的项目构建系统
•通过POM(project object model)提供一个项目的重要信息
•为最佳项目开发实践提供一个指导方针
接下来本文就通过Maven
的安装、基本的指令使用和一个实际的小例子来带你对Maven
的使用有一个大体的认识。此外,本文的样例基于JDK1.8
和Maven3
。
环境准备
在安装Maven
之前,首先要确保本地已安装JDK
并配置好了JAVA_HOME
环境变量,可以在cmd
通过以下命令进行验证:
echo %JAVA_HOME% # 输出 JAVA_HOME 环境变量值 java -version # 输出 Java 版本信息
如果正常输出了JDK
的安装路径及java
的版本信息,那么就可以开始进行下一步了,否则,你可能需要先到官网下载一个JDK
,并按照下图所示配置好环境变量:
安装Maven
在确认本地已安装好了JDK
并配置了环境变量后,我们就可以开始安装Maven
了,首先找到官网,然后找到安装包下载即可,本文以 3.6.3 版本为例:
在下载完成后,解压到本地文件夹即可,以我为例,我解压在 D 盘:
在解压完毕后,我们先进行环境变量的配置,配置一个名为M2_HOME
的环境变量,对应值为个人的Maven
文件夹位置:
然后在Path
系统变量中配置%M2_HOME%\bin
即可:
在配置完成并保存后,重新打开cmd
,输入以下命令进行验证,如果均得到正确信息,便表明已经安装成功:
echo %M2_HOME% # 输出 Maven 的安装位置 mvn -v # 输出 Maven 的版本信息
注意
你可能会疑惑为什么我们下载了Maven3
却要配置一个名为M2_HOME
的环境变量,这主要是因为在Maven1
时环境变量配置为MAVEN_HOME
,在Maven2
时改为了M2_HOME
,而在Maven3
则继续沿用了这个命名,不过在Maven3.5.0
以后,官方也舍弃了M2_HOME
,因此我们现在其实只需要在Path
中配置D:\apache-maven-3.6.3\bin
即可,不过本文依旧沿用了M2_HOME
。
安装目录介绍
在正式讲解Maven
的使用之前,我们先熟悉一下Maven
的安装目录中各个文件夹的内容及作用(基于Maven3.6.3
版本):
bin
该文件夹下包含了mvn
运行的脚本,这些脚本用来配置Java
命令,准备好classpath
和相关的Java
系统属性,然后执行Java命令。其中mvn
是基于UNIX
平台的shell
脚本,mvn.cmd
是基于Windows
平台的下的运行脚本。当我们在命令行中输入一条mvn
命令时,其实就是在调用这些脚本。此外该文件夹中还包含了mvnDebug
和mvnDebug.cmd
这两个文件,该脚本包含了mvn
脚本所有的功能,只是多了一条MAVEN_DEBUG_OPTS
的配置,用于调试Maven
。除此之外,该文件夹内还包含了m2.conf
和mvnyjp
文件,其中m2.conf
是classworlds
的配置文件,而mvnyjp
则是为了配合Yourkit profiler
的使用,关于classworlds
和Yourkit profiler
,本文不做介绍,感兴趣可以自行查找资料。
boot
该文件夹下只有一个plexus-classworlds
的jar
包和其相关的license
文件,plexus-classworlds
是一个类加载框架,Maven
使用该框架来加载自己的类库。
conf
该文件下包含了一个我们以后接触最多的settings.xml
文件,主要用于配置代理、镜像和插件等。
此外还包含了一个toolchains.xml
配置文件和一个logging
文件夹,其中toolchains.xml
主要是为了方便我们指定项目所使用的JDK
版本,需要配置maven-toolchains-plugin
插件一起使用,而logging
文件夹(内含一个名为simplelogger.properties
的配置文件)则用于配置我们在使用Maven
时的日志。
lib
该文件夹下包含了所有Maven
在运行时所需要的一些库文件,这里就不做具体介绍了。
其它
此外还有LICENSE
、NOTICE
、README.txt
用于说明开源协议和简单介绍的文件。
实战演练
下面我们就开始通过一个实际小案例来说明Maven
的基本使用,为了加深对Maven
中配置文件和基本指令的学习,我们就不使用IDEA
等集成Maven
的IDE
了,直接使用VS CODE
来进行接下来案例的讲解。
首先,我们先创建一个名为maven
的文件夹,然后通过VS CODE
打开,新建一个名为pom.xml
的文件夹,并在其中输入以下内容:
<?xml version="1.0" encoding="UTF-8"?> <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.butterfly.maven</groupId> <artifactId>demo</artifactId> <version>1.0-SNAPSHOT</version> <!-- 可选 --> <name>a demo maven project</name> </project>
下面对该文件中的内容进行简单介绍:
文件的第一行是XML
头,就像HTML
中也有<!DOCTYPE html>
头为了告诉标准通用标记语言解析器如何解析文档一般,在XML
这里主要是为了指定文档的版本和编码方式。紧接着是project
,主要声明了一些POM
相关的命名空间和xsd
元素,可以方便我们在使用IDE
时编辑XML
文档。在project
这个根元素下还有四个同级的元素,下面再一一介绍:
- modelVersion:制定了当前POM模型的版本,对于Maven2和Maven3来说,这个值固定为 4.0.0。
- groupId:定义了项目属于哪个组,一般都是对应公司或组织的域名反写并加上项目名,例如公司域名为abc.com,项目名为demo,那么groupId就是com.abc.demo。
- artifactId:定义了在当前Maven项目中的唯一的ID,当项目包含多个子项目时,我们就需要特别注意命名方式。
- version:指定了当前项目的版本,SNAPSHOT意思是快照,即代表当前项目属于不稳定的版本。
- name:声明了一个让用户更容易理解的项目名称,改元素属于可选项。
然后,我们就开始正式编写项目的主代码,我们首先按照Maven
规范,在maven
文件夹下创建一个src/main/java
目录,然后在该目录下再根据我们在XML
中groupId
和artifactId
的命名,创建文件:com/butterfly/maven/demo/Sum.java
,并写入以下内容:
package com.butterfly.maven.demo; public class Sum { private static int sum(int[] arr) { int sum = 0; for (int val : arr) { sum += val; } return sum; } public static void main(String[] args) { System.out.println(sum(new int[]{1, 3, 5, 7, 9})); } }
然后在项目的根目录下执行mvn clean compile
命令进行编译,可以得到以下输出(第一次执行会下载很多插件依赖,下面输出中省略了这些下载输出):
[INFO] Scanning for projects... [INFO] [INFO] ----------------------< com.butterfly.maven:demo >---------------------- [INFO] Building a demo maven project 1.0-SNAPSHOT [INFO] --------------------------------[ jar ]--------------------------------- [INFO] [INFO] --- maven-clean-plugin:2.5:clean (default-clean) @ demo --- [INFO] Deleting D:\Temp\maven\target [INFO] [INFO] --- maven-resources-plugin:2.6:resources (default-resources) @ demo --- [INFO] skip non existing resourceDirectory D:\Temp\maven\src\main\resources [INFO] [INFO] --- maven-compiler-plugin:3.1:compile (default-compile) @ demo --- [INFO] Changes detected - recompiling the module! [INFO] Compiling 1 source file to D:\Temp\maven\target\classes [INFO] ------------------------------------------------------------------------ [INFO] BUILD SUCCESS [INFO] ------------------------------------------------------------------------ [INFO] Total time: 1.975 s [INFO] Finished at: 2020-10-02T21:27:55+08:00 [INFO] ------------------------------------------------------------------------
其中clean
用于告诉Maven
清理输出目录target/
,compile
告诉Maven
编译项目主代码,从上面的输出中也可以看出Maven
首先执行了maven-clean-plugin:2.5:clean
进行删除了target
目录,然后执行了maven-resources-plugin:2.6:resources
,由于项目中不存在resources
文件,因此跳过了,最后执行了maven-compiler-plugin:3.1:compile
对主代码进行编译,并将编译的结果放到target/classes
目录下,如下图所示:
接下来,我们再编写测试的代码,首先我们依旧按照Maven
规范,在src/
目录下继续创建test/java
目录,然后在编写正式的测试代码之前,让我们先引入JUnit
的依赖,我们需要将pom.xml
进行如下修改:
<!-- 添加在 project 根元素下 --> <dependencies> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.13</version> <scope>test</scope> </dependency> </dependencies>
然后我们就可以编写我们的测试代码了,我们在src/test/java/
目录下,创建demo/SumTest.java
文件,并写入以下内容:
package demo; import org.junit.Test; import static com.butterfly.maven.demo.Sum.sum; import static org.junit.Assert.assertEquals; public class SumTest { @Test public void testSum() { assertEquals(10, sum(new int[]{1, 2, 3, 4})); } }
然后我们在根目录下开启终端,并运行mvn clean test
指令(第一次运行同样会下载一些插件,这里也省略了这些下载输出),可以在终端中得到以下信息:
[INFO] Scanning for projects... [INFO] [INFO] ----------------------< com.butterfly.maven:demo >---------------------- [INFO] Building a demo maven project 1.0-SNAPSHOT [INFO] --------------------------------[ jar ]--------------------------------- [INFO] [INFO] --- maven-clean-plugin:2.5:clean (default-clean) @ demo --- [INFO] Deleting D:\Temp\maven\target [INFO] [INFO] --- maven-resources-plugin:2.6:resources (default-resources) @ demo --- [INFO] skip non existing resourceDirectory D:\Temp\maven\src\main\resources [INFO] [INFO] --- maven-compiler-plugin:3.1:compile (default-compile) @ demo --- [INFO] Changes detected - recompiling the module! [INFO] Compiling 1 source file to D:\Temp\maven\target\classes [INFO] [INFO] --- maven-resources-plugin:2.6:testResources (default-testResources) @ demo --- [INFO] skip non existing resourceDirectory D:\Temp\maven\src\test\resources [INFO] [INFO] --- maven-compiler-plugin:3.1:testCompile (default-testCompile) @ demo --- [INFO] Changes detected - recompiling the module! [INFO] Compiling 1 source file to D:\Temp\maven\target\test-classes [INFO] [INFO] --- maven-surefire-plugin:2.12.4:test (default-test) @ demo --- [INFO] Surefire report directory: D:\Temp\maven\target\surefire-reports ------------------------------------------------------- T E S T S ------------------------------------------------------- Running demo.SumTest Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.091 sec Results : Tests run: 1, Failures: 0, Errors: 0, Skipped: 0 [INFO] ------------------------------------------------------------------------ [INFO] BUILD SUCCESS [INFO] ------------------------------------------------------------------------ [INFO] Total time: 3.166 s [INFO] Finished at: 2020-10-02T22:17:30+08:00 [INFO] ------------------------------------------------------------------------
根据输出可以发现,执行mvn clean test
同样也执行了mvn clean compile
中的clean
、resources
、compile
这三个指定,不同的是,这里还多了对测试包中进行的三个操作,分别是testResources
、testCompile
和test
,随后打印了执行单元测试后的输出,可以发现执行了一个测试(即为我们建立的testSum
测试方法),并且没有失败的测试。
注意
对于不同版本的Maven
,在第一次执行上述操作的时候,可能会有关于JDK
版本方面的报错,提示我们编译版本过低,这时就需要在pom.xml
中添加如下配置:
<!-- 添加在 project 根元素下 --> <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <configuration> <source>1.8</source> <target>1.8</target> </configuration> </plugin> </plugins> </build>
此外,由于Maven
在安装依赖时,默认是从国外网址下载,因此为了加快下载速度,我们需要配置国内的镜像,这时我们就需要对settings.xml
文件进行修改,这里建议在修改之前做一个备份。打开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>
还有一点需要注意的是,所有的依赖包默认下载的位置是~/.m2/repository
,这里的~
代表的个人的用户目录,对我而言就是对应C:/Users/zjw/.m2/repository
。因此,如果不想将jar
包放在 C 盘,就需要和mirrors
同级,然后加入以下配置:
<localRepository>D:/jar</localRepository>
这样,所有的依赖都会保存在D:/jar
目录下了。
打包及运行
在Maven
里,我们只要通过mvn clean package
命令就可以对项目进行打包了(默认打包类型为jar
),我们在cmd
中输入以上指令,可以得到下面的输出(省略了和以上指令中相同的前几个输出):
[INFO] [INFO] --- maven-jar-plugin:2.4:jar (default-jar) @ demo --- [INFO] Building jar: D:\Temp\maven\target\demo-1.0-SNAPSHOT.jar [INFO] ------------------------------------------------------------------------ [INFO] BUILD SUCCESS
执行完毕后,我们就可以在target/
目录下发现我们生成的jar
包了。此外,如果我们想要像引用其它jar
包一样,在其它的项目中引入我们自己的jar
包也是可以的,但是如果每次都要将jar
包一个一个地复制到其他项目中是非常麻烦的,但是通过Maven
,我们只需要一个mvn clean install
命令就可以将当前项目的jar
包安装到本地仓库:
可以发现和mvn clean package
相比,又多了如下几行输出:
[INFO] --- maven-install-plugin:2.4:install (default-install) @ demo --- [INFO] Installing D:\Temp\maven\target\demo-1.0-SNAPSHOT.jar to D:\jar\com\butterfly\maven\demo\1.0-SNAPSHOT\demo-1.0-SNAPSHOT.jar [INFO] Installing D:\Temp\maven\pom.xml to D:\jar\com\butterfly\maven\demo\1.0-SNAPSHOT\demo-1.0-SNAPSHOT.pom
按照信息,我们可以知道,我们生成的jar
包被保存在了D:/jar/com/butterfly/maven/demo/1.0-SNAPSHOT/
目录下,我们可以打开文件资源管理器进行验证:
这样,我们就可以在其它项目中,通过以下配置来引用我们自己的jar
包了:
<dependency> <groupId>com.butterfly.maven</groupId> <artifactId>demo</artifactId> <version>1.0-SNAPSHOT</version> </dependency>
不过,到目前为止,我们仍然没有运行主代码中的main
函数部分,由于默认生成的jar
包中缺少manifest
配置,因此上文生成的jar
包并没有办法直接运行,为了生成能够执行的jar
包,我们还需要在pom.xml
加入以下配置:
<plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-shade-plugin</artifactId> <version>1.2.1</version> <executions> <execution> <phase>package</phase> <goals> <goal>shade</goal> </goals> <configuration> <transformers> <transformer implementation="org.apache.maven.plugins. shade.resource.ManifestResourceTransformer"> <mainClass>com.butterfly.maven.demo.Sum</mainClass> </transformer> </transformers> </configuration> </execution> </executions> </plugin>
再次执行mvn clean install
命令,可以发现target/
目录下有两个jar
包:
其中orgin
开头的jar
包则对用我们之前无法直接执行的jar
包,另外一个则是可以直接执行的,我们可以进行测试:
大功告成!
总结
本文简单介绍了Maven
,并讲解了Maven
的安装和几个基本的命令的使用,在之后我还会继续讲解Maven
其他方面的知识,希望能够对你有所帮助。
参考资料
《Maven 实战》
加载全部内容