本文介绍项目管理工具Maven,是一个辅助性工具,官网:http://maven.apache.org。
1. Maven简介
1.1 软件是一个工程
记得本科中学过一门课程:《软件工程》,即将软件开发看成一项工程,在这项工程中涉及到人力物力和时间等等。软件工程指的是:为了能够实现软件的流水线式生产,在设计和构建软件时能够有一种规范和工程化的方法,人们便提出了软件工程概念。
软件开发需要涉及到很多步骤:
- 项目的需求分析。
- 设计项目步骤,使用哪些技术,需要多少人力物力时间。
- 组建团队,招人,购置设备(软硬件)。
- 开发人员写代码。开发人员需要测试自己写代码,重复多次测试。
- 测试人员,测试项目工程是否符合要求。测试开发人员提交的代码–>如果有问题,开发人员修改,提交代码–>测试人员再次测试代码–>重复上面步骤,直到测试代码通过。
上面第5步骤,测试和修改需要重复多次,因此非常费时费力,这时候出现了Maven【当然,Maven不仅仅具有此功能】。
1.2 传统项目中存在的问题
- 项目中存在很多模块,模块之间存在很多关系,手动管理之间的关系比较繁琐。
- 需要很多第三方功能(jar包),需要手工从网络中获取,比较麻烦,需要从不从途径一个个获取
- 需要管理jar包的版本,以及版本的更新。
- 需要管理jar包之间的依赖,比如项目使用a.jar文件,而a.jar需要用到b.jar里面的类,因此必须首先获取到b.jar才可以,然后才能使用a.jar。此时a.jar需要b.jar这个关系叫做依赖。
由上可知,对于第三方jar包以及之间的版本和依赖,这种关系管理十分复杂。因此,maven诞生了。
1.3 Maven概述
maven可以做以下事情
- maven可以管理jar文件
- 自动下载jar和他的文档,源码等
- 管理jar之间的依赖,比如a.jar需要b.jar,此时,maven会自动下载b.jar
- 管理jar的版本
- 帮助编译程序,把java编译为class
- 帮助测试代码是否正确
- 帮助打包文件,形成jar文件或者war文件
- 帮助部署项目
上面的5678步骤统称为构建,构建是面向过程的,就是一些步骤,完成项目代码的编译,测试,运行,打包和部署等。maven支持的构建包括有:
- 清理,把之前项目编译生成的东西删除掉,为新的编译代码做准备。
- 编译,把程序源代码编译为执行代码,可以批量编译整个项目所有的java文件。
- 测试,maven可以执行测试程序代码,验证功能是否正确,可以批量测试很多功能。
- 报告,生成测试结果的文件,测试是否通过。
- 打包,把项目中所有的class文件、配置文件等所有资源放到一个压缩文件中,这个压缩文件就是项目的结果文件,通常普通Java程序,压缩文件是jar扩展名,而web应用,压缩文件扩展名是war。
- 安装,将5中生成的jar或者war安装到本机maven仓库。
- 部署,把程序安装好可以执行。
一般情况下,用maven执行上面1-6步骤。
1.4 Maven核心概念
Maven的核心概念有如下几个:
POM
这是一个文件,pom.xml,即project object model的简称,将项目看成一个模型,控制maven构建项目的过程,管理jar依赖。
预定的目录结构
maven项目的目录和位置都是规定好的。
坐标
是一个唯一的字符串,用来表示资源的。
依赖管理
管理项目使用的jar文件
仓库管理(了解)
仓库,资源存放的位置
生命周期(了解)
maven工具构建项目的过程,即生命周期
插件和目标(了解)
执行maven构建的过程用到的工具就是创建,比如clean、install等
继承(高级)
聚合(高级)
本文主要看1-7个概念。
1.5 安装Maven环境
官网下载bin.zip安装包,解压到非中文目录即可。并配置系统变量,设置 M2_HOME
的值为maven的安装目录D:\profession\maven\apache-maven-3.6.3
。并将M2_HOME
/bin 添加到系统环境变量path中。注意,maven是用java写的,因此需要有java环境,即JAVA_HOME变量,
- 在解压缩有的bin目录下,有一个mvn.cmd命令工具,该命令用来执行maven构建项目的命令,比如mvn clean等。
- 在conf目录下,有settings.xml,是maven工具的配置文件。
- 在lib目录下,则是maven命令所用到的jar包。
打开cmd,输入mvn --version
查看maven的版本,即安装成功。此时maven已经安装成功,可作为一个独立的工具使用。
1.6 settings.xml文件
2. Maven的核心概念
2.1 Maven工程约定的目录结构
约定是大家都认可的,可以破坏,但应尽肯能遵守。
每一个maven项目在磁盘中都是一个文件夹(项目),在这个文件夹中,目录结构如下:
- src
- main:放置主程序,源代码和配置文件
- java:java源码
- resources:配置文件
- test:测试代码和文件的,可以没有
- java:测试使用的java源码
- resources:测试使用的配置文件
- main:放置主程序,源代码和配置文件
- target:编译成功后生成的文件存放的位置
- pom.xml:maven项目的核心文件,必须有
1 | Hello/ |
在Hello目录下【即在pom.xml同级目录下】,执行mvn complie
命令会编译main目录下所有的java文件,由于首次使用,会自动从中央仓库(https://repo.maven.apache.org)下载大量的jar包(插件),并将这些插件存储到默认的本地仓库中(C:\Users\用户名\\.m2\repository)
经过一段时间下载后,成功编译显示如下内容。此时出现了与src平级的target目录。
由于上面默认是将jar文件下载到C盘中,可以在settings.xml文件中配置下载的本地仓库位置。注意,一般情况下,在修改前对该文件进行备份,防止修改出现错误无法还原最开始的版本。
1 | <localRepository>D:/profession/maven/maven_repository</localRepository> |
2.2 pom文件
pom是project object model的简称,表示pom.xml文件,是maven的灵魂,整个项目都是通过该文件来配置的。pom.xml文件的大概标签内容如下所示:
1 |
|
- 以标签
<?xml version="1.0" encoding="UTF-8"?>
开始放在第一行。 - 下面是
<project>
标签,所有的内容都在<project>
标签里面,表示对当前项目的设置。 <modelVersion>
表示将本项目对象模型的版本,目前固定为4.0.0,无需改变。<groupId>
、<artifactId>
、<version>
三者分别表示当前项目所属组织、项目名以及版本号,三者构成了本项目的坐标,可唯一标识本项目。<dependencies>
表示本项目所需要的依赖集,<dependency>
则表示单个依赖,里面通过坐标来具体表示。可以有多个依赖。maven会根据坐标在本地仓库、私服、镜像等依次查询,直到找到为止。<packaging>
,表示本项目打包的类型,默认为jar。<properties>
用于配置属性。<build>
表示与构建项目相关的配置,比如插件配置。<parent>
表示继承,即子模块可以继承父模块的配置信息。<modules>
表示聚合。
2.3 仓库
由于maven工具执行的操作需要很多插件,因此需要从中央仓库地址下载,并将这些插件放置到本机仓库中。并且在写代码中用到的其他依赖也都会从中央仓库下载并保存到本机仓库中。
随机项目的堆积,仓库内容也会越来越丰富,这样后续可以不用下载,直接从仓库中获取。
其实,maven在需要用到jar文件时,会首先从本地仓库查询,找不到,则从中央仓库中下载备份获取。
综上,仓库是用来存放:
- maven使用的插件(各种jar)
- 项目使用的第三方库,jar包
仓库分为本地仓库和远程仓库两种:
- 本地仓库就是个人计算机上的文件夹,存放各种jar
- 远程仓库,在互联网上的网站服务,远程仓库分为:
- 中央仓库:最权威的,所有的开发人员都共享使用的一个集中的仓库。如https://repo.maven.apache.org。
- 中央仓库镜像,为了缓解中央仓库的并发压力,对该服务器进行性镜像备份。
- 私有仓库(私服),公司内部自行搭建的,非对外使用。
仓库的使用,不需要人为参与。步骤如下:
- 开发人员需要使用mysql的jar包
- maven首先查询本地仓库,如果本地仓库没有该jar包则查询设置的私服,如果私服有,则在本地备份一份。【如果没有设置私服,则跳过本步】
- 如果私服没有,则查询中央仓库镜像,如果有,则在私服和本地备份一份。
- 如果中央仓库镜像进行也没有,则查询中央仓库,如果有,则在镜像、私服和本地备份一份。
2.4 Maven的生命周期
对项目的构建是建立在生命周期模型上的,它明确定义项目生命周期各个阶段,并且对于每一个阶段都提供相对应的命令,对开发者而言仅仅需要掌握一小堆的命令就可以完成项目各个阶段的构建工作。
如前面所说,生命周期包括编译测试打包部署等阶段。构建项目时按照生命周期顺序构建,每一个阶段都有特定的插件来完成。不论现在要执行生命周期中的哪个阶段,都是从这个生命周期的最初阶段开始的。
2.5 Maven的常用命令
Maven提供一个项目构建的模型,把清理、编译、测试、打包、部署等都对应成一个个的生命周期阶段,并对每一个阶段提供相应的命令,程序员只需要掌握一小堆命令,就可以完成项目的构建过程。具体命令如下:
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容器中。
注意,这些命令必须在项目根目录下执行,即在pom.xml平级目录中执行。而且,在执行每个命令的时候,都会把前面的生命周期命令都执行一遍,比如在执行mvn test
的时候,会把123都执行一遍。
另外,在
mvn compile
命令结果中,可以看到,这条命令其实是由两个插件来实现的,分别是maven-resources-plugin
和maven-compiler-plugin
。其他命令也是如此。
2.6 插件
maven命令执行时,真正完成该功能的就是插件,其实就是jar文件,一些java类。比如clean、compile等功能,都是java编写的工具类。
如上所说,这些插件有具体的版本,那么可以配置吗,答案是可以的,即在pom.xml文件中的<build>
标签中设置。如
1 | <build> |
2.7 坐标(gav)
1 | <groupId>com.bjpwoernode.maven</groupId> |
依赖是一个资源,在网络中有各种各样的资源,将其下载后,保留到本地,此时如何更加方便地定位且不重复呢?Maven采用坐标的形式,即用<groupId>
、<artifactId>
和<version>
三个标签来表示。
- groupId表示组织id,一般是公司域名的倒写,因为域名具有唯一性,其倒写也具有唯一性。域名倒写或者域名倒写+项目名,比如“com.baidu”和“com.baidu.appolo”。
- artifactId表明项目名称,或者模块名称,对象groupId中的项目中的子项目。
- version表示项目的版本号,比如1.1.0或者开发版本-SNAPSHOT。
通过三个标签,可以唯一的确定一家公司以及其唯一的子项目,此外,根据版本号,则唯一确定了一个项目(jar包、资源等)。在本地仓库中,坐标中的三个标签都是作为文件夹名称出现的。
对于一些公共资源jar包的依赖坐标,可通过www.mvnrepository.com进行搜索并引入到项目中。
2.8 依赖(dependency)
同上,依赖就是一个jar包,一种资源。既然是资源,就需要定位,即需要坐标。在上面坐标的基础上,添加的dependency标签就表示了一个依赖。由于可以需要多个依赖,此时,在pom文件中则需要对依赖进行再次标记,即dependencies标签。
1 | <dependencies> |
2.9 单元测试
单元测试指的是类中的方法,每一个方法都是独立测试的,方法是测试的基本单元。maven借助单元测试,可以批量测试类中的方法是否符合预期。
在pom.xml文件中加入junit依赖。
1 | <dependency> |
在项目目录下src/test/java
目录下,创建测试程序,推荐的测试类和方法名如下:
- 测试类的名称:Test + 要测试的类名
- 测试方法的名称:Test + 方法名称
注意,测试方法有如下规定:
- 方法必须是public
- 方法必须没有返回值
- 方法名称是自定义的,推荐 Test + 方法名称
- 方法上面加上 @Test 注解
源程序如下:
1 | public class HelloMaven{ |
测试程序如下,直接运行testAdd()方法即可:
1 | // 导入junit包中的方法以及注解 |
3. Maven在IDEA中的应用
由上面可知,maven其实是一个独立的工具,和Java、Python、Nmap等一样,是独立的程序,为了方便开发,IDEA可以集成Maven,可在IDEA中通过UI来使用maven。
3.1 IDEA集成Maven
3.2 IDEA创建Maven版java工程
3.3 IDEA创建Maven版web工程
3.4 IDEA中导入Maven工程(module)
4. 依赖管理
4.1 依赖的范围
5. Maven常用设置
5.1 全局变量
5.2 指定资源位置
6. 备注
参考B站《动力节点》。