文章目录
Maven是什么
- Maven是项目管理工具,对软件项目提供构建、依赖管理与信息管理
- Maven是Apache下的Java开源项目
- Maven为java项目提供了统一的管理方式,已成为业界标准
Maven核心特性
- 项目设置遵循统一的规则,保证不同开发环境的兼容性
- 强大的依赖管理,项目依赖组件可以自动下载、自动更新
- 可扩展的插件机制,使用简单,功能丰富
Maven安装配置
本教程是在Windows操作系统下安装,其他系统下安装请参考网络教程
下载Maven
打开Maven官网:http://maven.apache.org,在下载页面根据自己需求下载对应文件,这里下载apache-maven-3.8.4-bin.zip
,具体可参考下图:
安装Maven
解压Maven压缩包
- 将下载下来的
apache-maven-3.8.4-bin.zip
,直接解压到对应磁盘下即可,这里解压到D盘,打开解压后的文件目录如下:
配置环境变量
- 将
Maven
的bin
目录配置到环境变量中:新建系统变量,变量名为M2_HOME
,变量值为bin
目录地址
验证是否安装成功
- 打开命令提示符,输入mvn -version,如果看到如下类似信息,说明Maven在Windows上安装成功(这里仅做展示,不用在意截图中的版本),如果没有看到类似信息,重启电脑。
配置Maven
Maven全局配置文件settings.xml
在Maven安装目录下的conf文件夹,可以进行用户自定义配置。
配置本地仓库位置
Maven安装好后,配置的默认本地仓库在%user%/.m2/respository
目录下,一般我们会将其配置到其他磁盘下,也可不配:
<localRepository>D:/repository</localRepository>
配置镜像
为了更好的下载速度,我们会选用国内镜像,这里配置的是阿里云镜像:
<!-- 默认的中央仓库有时候甚至连接不通。一般使用阿里云镜像库即可。-->
<!-- 阿里云镜像-->
<mirror>
<!--该镜像的唯一标识符。id用来区分不同的mirror元素 -->
<id>alimaven</id>
<!--镜像名称-->
<name>aliyun maven</name>
<!--该镜像的URL。构建系统会优先考虑使用该URL,而非使用默认的服务器URL-->
<url>http://maven.aliyun.com/nexus/content/groups/public/</url>
<mirrorOf>central</mirrorOf>
</mirror>
Maven项目的标准结构
src
|--main
|--java 源代码目录
|--resources 资源目录,保存配置文件、静态图片等
|--test
|--java 测试源代码目录
|--resources 测试资源目录
|--target 项目输出的目录,用于存储jar,war文件
|--classes 编译后的class文件目录
|--test-classes 编译后的测试class文件目录
pom.xml Maven工程配置文件:项目(Project)对象(Object)模型(Model)文件
Maven的依赖管理
- maven利用
dependency(依赖)
自动下载、管理第三方jar - 在
pom.xml
文件中配置项目依赖的第三方组件 - maven自动将依赖从远程仓库下载至本地仓库,并在工程中引用
坐标
<dependencies>
<dependency>
<!-- groupId:公司或组织域名倒序 -->
<groupId>mysql</groupId>
<!-- artifactId:模块名 -->
<artifactId>mysql-connector-java</artifactId>
<!-- version:版本号 -->
<version>8.0.21</version>
</dependency>
</dependencies>
groupId
、artifactId
、versioin
简称GAV
(Maven坐标),是用来唯一标识jar包的。如果不清楚jar包的坐标信息,可以在https://search.maven.org/中搜索:
Maven仓库
Maven管理资源的位置。仓库里面包含依赖(jar包)和插件(plug-in)。Maven仓库分为本地仓库和远程仓库,而远程仓库又包括私服和中央仓库。
Maven常用命令
mvn compile
:执行mvn compile
命令,完成编译操作。执行完毕后,会生成target目录,该目录中存放了编译后的字节码文件。mvn test
:执行mvn test
命令完成单元测试操作,执行完毕后,会在target
目录中生成三个文件夹:surefire
、surefire-reports
(测试报告)、test-classes
(测试的字节码文件)。mvn clean
:执行mvn clean
命令,执行完毕后,会将target
目录删除。mvn package
:执行mvn package
命令完成打包操作,执行完毕后,会在target
目录中生成一个文件,该文件可能是jar、war
,具体要看pom.xml
中配置的打包方式,,默认为jar包。mvn install
:执行mvn install
命令,完成将打好的jar包安装到本地仓库的操作,执行完毕后,会在本地仓库中出现安装后的jar包,方便其他工程引用。
组合指令
mvn clean compile
命令:先执行clean
,再执行compile
,通常应用于上线前执行,清除测试类。mvn clean test
命令:先执行clean
,再执行test
,通常应用于测试环节。mvn clean package
命令,先执行clean
,再执行package
,将项目打包,通常应用于发布前。
Maven指令的生命周期
Maven有三套相互独立的生命周期,每套之间相互独立:
Clean Lifecycle:清理生命周期
在进行真正的构建之前进行一些清理工作,Clean生命周期一共包含了三个阶段:
pre-clean
执行一些需要在clean之前完成的工作。clean
移除所有上一次构建生成的文件。post-clean
执行一些需要在clean之后立刻完成的工作。
Default Lifecycle:默认生命周期
构建的核心部分,包括编译,测试,打包,部署等等环节。默认生命周期包含了以下的阶段(该阶段经过简化,实际上更加复杂):
验证(validate)
: 验证项目是否正确,所有必要的信息可用。编译(compile)
: 编译项目的源代码。测试(test)
:使用合适的单元测试框架测试编译的源代码。这些测试不应该要求* 代码被打包或部署。打包(package)
:采用编译的代码,并以其可分配格式(如JAR)进行打包。验证(verify)
:对集成测试的结果执行任何检查,以确保满足质量标准。安装(install)
: 将软件包安装到本地存储库中,用作本地其他项目的依赖项。部署(deploy)
:在构建环境中完成,将最终的包复制到远程存储库以与其他开发人员和项目共享。
Site Lifecycle:站点生命周期
生成项目报告,站点,发布站点,项目过程中使用的不多,简单了解即可。
pre-site(预站点)
:执行一些需要在生成站点文档之前的工作。site(站点)
:生成项目的站点文档。post-site(后站点)
:执行一些需要在生成站点文档之后完成的工作,并且为部署做准备。site-deploy(站点部署)
:将生成的站点文档部署到特定的服务器上。
Maven依赖范围管理
什么是依赖范围
依赖范围就是我们依赖的jar包在我们maven项目生命周期中作用的范围。不同的依赖会使用不同的classpath
,在Maven中依赖的域有这几个:import、provided、runtime、compile、system、test
。默认取值为compile
。
都有哪些依赖范围以及这些依赖范围的作用范围
Maven依赖传递
什么是传递依赖
在maven中,依赖是可以传递的,假设存在三个项目,分别是项目A,项目B以及项目C,假设C依赖B,B依赖A,那么我们可以根据maven项目依赖的特征不难推出项目C也依赖A。
Maven依赖冲突
由于依赖传递现象的存在,spring-webmvc-5.3.3
依赖spring-beans-5.3.3
,spring-aop-5.0.2
依赖spring- beans-5.0.2
, 但是发现spring-bean-5.0.2
加入到了工程中,而我们希望spring-beans-5.3.3
加入工程。这就造成了依赖冲突。
Maven依赖冲突解决方案
- 使用maven提供的依赖调解原则
- 第一声明者优先原则
- 路径近者优先原则
- 排除依赖
- 锁定版本
使用maven提供的依赖调解原则
第一声明者优先原则
在pom文件中定义依赖,以先声明的依赖为准。其实就是根据坐标导入的顺序来确定最终使用哪个传递过来的依赖。仅需了解,实际项目过程中不会采用该方式解决依赖冲突问题。
路径近者优先原则
在pom文件定义依赖,以路径近者为准。还是上述情况,spring-aop
和spring-webmvc
都会传递过来spring-beans
,那如果直接把spring-beans
的依赖直接写到pom文件中,那么项目就不会再使用其他依赖传递来的spring-beans
,因为自己直接在pom中定义 spring-beans要比其他依赖传递过来的路径要近。
排除依赖
可以使用exclusions标签将传递过来的依赖排除出去:
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.3.3</version>
<exclusions>
<exclusion>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
锁定版本
采用直接锁定版本的方法确定依赖jar包的版本,版本锁定后则不考虑依赖的声明顺序或依赖的路径以锁定的版本为准添加到工程中,此方法在企业开发中经常使用。版本锁定的使用方式:
- 第一步:在
dependencyManagement
标签中锁定依赖的版本 - 第二步:在
dependencies
标签中声明需要导入的maven
坐标
在dependencyManagement标签中锁定依赖的版本
注意:注意:pom文件中使用
dependencyManagement
标签进行依赖jar的版本锁定,并不会真正将jar包导入到项目中,只是对这些jar的版本进行锁定。项目中使用哪些jar包,还需要在dependencies
标签中进行声明。
<!--依赖jar包版本锁定-->
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>5.3.3.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.3.3.RELEASE</version>
</dependency>
</dependencies>
</dependencyManagement>
在dependencies标签中声明需要导入的maven坐标
<dependencies>
<!-- 由于前面已经在dependencyManagement标签中锁定了spring-bean和spring-context的版本,此处只需要导入groupdId和artifactId即可,无需再指定version-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
</dependency>
</dependencies>
分模块构建Maven工程
在企业项目开发过程中,由于项目规模庞大,业务复杂,参与的人员比较多,一般会通过合理的模块拆分将一个大型的项目拆分为N多个小模块,分别进行开发。而且拆分出的模块可以非常容易的被其他模块复用。常见的拆分方式有两种:
- 按照业务模块进行拆分:每个模块拆分成一个maven工程,例如将一个项目分为用户模块、订单模块、购物车模块等,每个模块对应就是一个maven工程。
- 按照层进行拆分:例如持久层、业务层、表现层等,每个层对应就是一个maven工程。
继承概念 AND 聚合概念
继承
在Java语言中,类之间是可以继承的,通过继承,子类就可以引用父类中非private的属性和方法。同样,在maven工程之间也可以继承,子工程继承父工程后,就可以使用在父工程中引入的依赖。例如在聚合多个项目时,如果这些被聚合的项目中需要引入相同的Jar,那么可以将这些Jar写入父pom中,各个子项目继承该pom即可。继承的目的是为了消除重复代码(简化pom.xml配置,简化groupId,artifactId,version的书写 ),还可以锁定子工程依赖版本。
被继承的Maven项目中的POM的部分定义是:
<groupId>com.fpz</groupId>
<artifactId>fpz-Parent</artifactId>
<version>1.0.0</version>
<packaging>pom</packaging>
<!-- 将需要继承的Jar包的坐标放入标签即可,版本锁定章节已将如何使用 -->
<dependencyManagement>
<dependencies>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>28.0-jre</version>
</dependency>
</dependencies>
</dependencyManagement>
注意:被继承的maven工程通常称为父工程,父工程的打包方式必须为pom,所以我们区分某个maven工程是否为父工程就看这个工程的打包方式是否为pom。
继承的Maven项目中的POM的关键部分就是:
<parent>
<groupId>com.fpz</groupId>
<artifactId>fpz-Parent</artifactId>
<version>1.0.0</version>
<relativePath>../fpz-Parent/pom.xml</relativePath>
</parent>
注意:继承其他maven父工程的工程通常称为子工程在pom.xml文件中通过parent标签进行父工程的继承
优缺点
- 优点:父子项目,合理有效的附庸依赖jar包,子项目互相独立,更加便于敏捷开发和独立管理。
- 缺点:父子项目,项目之间的系统集成性能比较差。
聚合
在maven工程的pom.xml文件中可以使用标签将其他maven工程聚合到一起,聚合的目的是为了进行统一操作。例如拆分后的maven工程有多个,如果要进行打包,就需要针对每个工程分别执行打包命令,操作起来非常繁琐。这时就可以使用标签将这些工程统一聚合到maven工程中,需要打包的时候,只需要在此工程中执行一次打包命令,其下被聚合的工程就都会被打包了。
<modules>
<module>fpz-mapper</module>
<module>fpz-model</module>
<module>fpz-service</module>
<module>fpz-web</module>
</modules>
优点
- 优点:项目之间的整体性较高,便于系统集成和维护。
Maven私服搭建
什么是私有服务器
私服是架设在局域网的一种特殊的远程仓库,目的是代理远程仓库及部署第三方构件。有了私服之后,当 Maven 需要下载构件时,直接请求私服,私服上存在则下载到本地仓库;否则,私服请求外部的远程仓库,将构件下载到私服,再提供给本地仓库下载。
私有服务器搭建
我们可以使用专门的 Maven 仓库管理软件来搭建私服,比如:Apache Archiva,Artifactory,Sonatype Nexus
。这里我们使用 Sonatype Nexus
。具体可参考maven私服搭建教程
参考资料: