概叙
什么是Maven?
- Maven(读作“马文”)是一个软件项目管理和构建工具,主要用于Java项目。它简化了项目的构建、依赖管理和项目信息管理。
- Maven 是一个意第绪语单词,意思是 知识的积累器,最初是为了简化 Jakarta Turbine 项目的构建过程。有几个项目,每个项目都有自己的 Ant 构建文件,但都略有不同。JAR 已签入 CVS。我们需要一种构建项目的标准方法、项目组成的清晰定义、发布项目信息的简单方法以及跨多个项目共享 JAR 的方法。
-
Maven基于项目对象模型 (POM) 的概念,Maven 可以通过中央信息来管理项目的构建、报告和文档。
maven的环境变量
Maven核心原理:项目对象模型 (Project Object Model)
- 项目对象模型(POM):Maven通过一个XML文件
pom.xml
来描述项目的基本信息、依赖、插件和构建流程。Maven 包含了一个项目对象模型 (Project Object Model),一组标准集合,一个项目生命周期(Project Lifecycle),一个依赖管理系统(Dependency Management System),和用来运行定义在生命周期阶段 (phase)中插件(plugin)目标(goal)的逻辑。 - 构建生命周期:Maven定义了一个标准化的构建生命周期,包括编译、测试、打包、部署等阶段。开发者可以通过执行生命周期的不同阶段来完成项目的构建和部署。
- 依赖管理:Maven通过集中仓库管理项目的依赖,自动下载和管理项目所需的库和插件,避免了手动管理依赖的麻烦。
<!-- 依赖关系 --> <dependencies> <!-- 此项目运行使用 junit,所以此项目依赖 junit --> <dependency> <!-- junit 的项目名称 --> <groupId>junit</groupId> <!-- junit 的模块名称 --> <artifactId>junit</artifactId> <!-- junit 版本 --> <version>4.9</version> <!-- 依赖范围:单元测试时使用 junit --> <scope>test</scope> </dependency>
- 插件体系:Maven的功能主要通过插件来扩展,用户可以根据项目需求选择和配置不同的插件,完成自定义的构建任务。
Maven工作流程
使用maven完成项目的构建,项目构建包括:清理,编译,部署等过程,maven将这些过程规范为一个生命周期,如下所示是生命周期的各阶段
maven 通过执行一些简单命令即可实现上边生命周期的各各过程,比如执行 mvn compile 执行编译、 执行 mvn clean 执行清理。
- 解析POM文件:Maven读取
pom.xml
文件,解析出项目的依赖、插件和构建配置。 - 下载依赖:根据
pom.xml
中声明的依赖,Maven从本地仓库或远程仓库下载所需的依赖项。 - 执行构建生命周期:用户通过命令(如
mvn clean package
)执行Maven的构建生命周期阶段,Maven根据生命周期阶段执行相应的插件目标,完成诸如编译、测试、打包等操作。 - 生成构建结果:根据执行的生命周期阶段,Maven生成相应的输出,如JAR文件、WAR文件等。
-
scope依赖作用域:也可以称作依赖范围:maven中的的依赖,会根据场景和所处阶段发生变化。
scope属性有五种:
扫描二维码关注公众号,回复: 17640427 查看本文章
system:不推荐使用,使用system作用域不会去本地仓库寻找依赖,要指定本地绝对路径。
Maven的优缺点
- 优点
- 标准化的项目管理:Maven通过标准化的POM文件和构建生命周期,简化了项目管理和构建过程,降低了开发者对构建工具的依赖。
- 强大的依赖管理:Maven通过仓库管理依赖,自动化依赖的下载、安装和管理,简化了依赖冲突的解决。
- 丰富的插件生态:Maven拥有庞大且活跃的插件生态,几乎可以扩展任何构建需求,支持自定义构建流程。
- 跨平台支持:Maven可以在任何操作系统上运行,支持多种构建环境。
- 支持多模块项目:Maven非常适合大型多模块项目,通过统一的构建和管理方式,提升了开发效率。
- 缺点
- 学习曲线陡峭:对于新手来说,Maven的概念和配置可能较为复杂,需要时间和实践来掌握。
- 配置复杂性:虽然Maven通过POM文件简化了项目配置,但在复杂项目中,
pom.xml
文件可能变得冗长和难以维护。 - 性能问题:在处理非常大的项目或复杂的依赖关系时,Maven的性能可能会显得不够理想,构建时间较长。
- 版本管理的挑战:在多模块项目中,依赖版本的管理可能较为复杂,需要仔细规划和维护。
Maven的目标
Maven 的主要目标是让开发人员在最短的时间内了解开发工作的完整状态。为了实现这一目标,Maven 处理了几个需要关注的领域:
- 使构建过程变得简单
- 提供统一的构建系统
- 提供优质项目信息
- 鼓励更好的开发实践
Maven约定配置
Maven 提倡使用一个共同的标准目录结构,Maven 使用约定优于配置的原则,大家尽可能的遵守这样的目录结构。如下所示:
目录 | 目的 |
---|---|
${basedir} | 存放pom.xml和所有的子目录 |
${basedir}/src/main/java | 项目的java源代码 |
${basedir}/src/main/resources | 项目的资源,比如说property文件,springmvc.xml |
${basedir}/src/test/java | 项目的测试类,比如说Junit代码 |
${basedir}/src/test/resources | 测试用的资源 |
${basedir}/src/main/webapp/WEB-INF | web应用文件目录,web项目的信息,比如存放web.xml、本地图片、jsp视图页面 |
${basedir}/target | 打包输出目录 |
${basedir}/target/classes | 编译输出目录 |
${basedir}/target/test-classes | 测试编译输出目录 |
Test.java | Maven只会自动运行符合该命名规则的测试类 |
~/.m2/repository | Maven默认的本地仓库目录位置 |
使构建过程变得简单
虽然使用 Maven 并不能消除了解底层机制的需要,但 Maven 确实使开发人员免于了解许多细节。
提供统一的构建系统
Maven 使用其项目对象模型 (POM) 和一组插件来构建项目。一旦熟悉了一个 Maven 项目,您就知道所有 Maven 项目是如何构建的。这可以在浏览许多项目时节省时间。
提供优质项目信息
Maven 提供有用的项目信息,这些信息部分取自 POM,部分从项目源生成。例如,Maven可以提供:
- 直接从源代码管理创建的更改日志
- 交叉引用来源
- 由项目管理的邮件列表
- 项目使用的依赖项
- 包括覆盖率的单元测试报告
第三方代码分析产品还提供 Maven 插件,将其报告添加到 Maven 给出的标准信息中。
Maven插件的分类和功能
Maven的核心是一个插件执行框架;所有工作都是由插件完成的。
Available Plugins指的是在Maven中可用的插件集合,这些插件可以帮助开发者完成各种构建、测试、打包、部署等任务。
Maven是一个项目管理和自动化构建工具,它通过插件机制来扩展功能。
寻找要执行的特定目标?
Maven插件可以分为核心插件和第三方插件:
- 核心插件:这些是Maven自带的插件,如
maven-compiler-plugin
用于编译代码,maven-deploy-plugin
用于部署项目等。 - 第三方插件:由社区或第三方提供的插件,如
spring-boot-maven-plugin
用于Spring Boot项目的构建和运行。
此页列出了核心插件和其他插件。有构建插件和报告插件:
- 构建插件Build plugins :将在生成期间执行,并且应在
<构建/>
POM中的元素。 - 报告插件Reporting plugins:将在站点生成期间执行,并且应在
<报告/>
POM中的元素。由于报告插件的结果是生成站点的一部分,因此报告插件应该国际化和本地化。您可以阅读更多关于我们插件的本地化以及您可以如何提供帮助。
下面是一些常用插件的列表:
插件 | 描述 |
---|---|
clean | 构建之后清理目标文件。删除目标目录。 |
compiler | 编译 Java 源文件。 |
surefile | 运行 JUnit 单元测试。创建测试报告。 |
jar | 从当前工程中构建 JAR 文件。 |
war | 从当前工程中构建 WAR 文件。 |
javadoc | 为工程生成 Javadoc。 |
antrun | 从构建过程的任意一个阶段中运行一个 ant 任务的集合。 |
要查看最新列表,请浏览Maven存储库,特别是 org/apache/maven/plugins子目录。(插件根据类似于标准Java包命名约定的目录结构进行组织)
插件 | 类型* | 版本 | 发布日期 | 说明 | 源码库信息 | 问题跟踪 |
---|---|---|---|---|---|---|
核心插件 | 对应于默认核心阶段(即清理、编译)的插件。他们也可能有多个目标。 | |||||
清洁的 | B类 | 3.3.1 | 2023-06-14 | 构建后进行清理。 | 吉特/github | 吉拉·麦克林 |
编译器 | B类 | 3.11.0 | 2023-02-14 | 编译Java源代码。 | 吉特/github | Jira MCOMPILER公司 |
部署 | B类 | 3.1.1 | 2023-03-21 | 将构建的工件部署到远程存储库。 | 吉特/github | 吉拉·麦德普洛伊 |
故障保护 | B类 | 3.1.2 | 2023-06-03 | 在隔离的类加载器中运行JUnit集成测试。 | 吉特/github | Jira SUREFIRE公司 |
安装 | B类 | 3.1.1 | 2023-03-21 | 将构建的工件安装到本地存储库中。 | 吉特/github | 吉拉·明斯塔尔 |
资源 | B类 | 3.3.1 | 2023-03-21 | 将资源复制到输出目录,以便包含在JAR中。 | 吉特/github | 吉拉先生 |
网站 | B类 | 2010年3月4日 | 2023-10-07 | 为当前项目生成站点。 | 吉特/github | Jira MSITE公司 |
万无一失 | B类 | 3.1.2 | 2023-06-03 | 在隔离的类加载器中运行JUnit单元测试。 | 吉特/github | Jira SUREFIRE公司 |
验证器 | B类 | 1.1 | 2015-04-14 | 对集成测试有用-验证特定条件的存在。 | 吉特/github | 吉拉·MVERIFIER |
包装类型/工具 | 这些插件与打包各自的工件类型有关。 | |||||
耳朵 | B类 | 3.3.0 | 2022-10-18 | 从当前项目生成EAR。 | 吉特/github | 吉拉·梅厄 |
电子束 | B类 | 3.2.1 | 2022-04-18 | 从当前项目构建EJB(和可选客户端)。 | 吉特/github | 吉拉MEJB |
罐子 | B类 | 3.3.0 | 2022-09-12 | 从当前项目构建JAR。 | 吉特/github | 吉拉MJAR |
放射性核素 | B类 | 3.0.0 | 2022-07-17 | 根据当前项目构建RAR。 | 吉特/github | 吉拉MRAR |
战争 | B类 | 3.4.0 | 2023-06-11 | 从当前项目构建WAR。 | 吉特/github | 吉拉MWAR |
应用程序客户端/acr | B类 | 3.1.0 | 2018-06-19 | 从当前项目构建一个JavaEE应用程序客户端。 | 吉特/github | 吉拉MACR |
阴影 | B类 | 3.5.1 | 2023-09-21 | 从当前项目构建Uber-JAR,包括依赖项。 | 吉特/github | 吉拉·姆沙德 |
来源 | B类 | 3.3.0 | 2023-05-17 | 从当前项目构建一个source-JAR。 | 吉特/github | Jira MSOURCES公司 |
jlink公司 | B类 | 3.1.0 | 2020-12-28 | 构建Java运行时映像。 | 吉特/github | Jira MJLINK公司 |
jmod公司 | B类 | 3.0.0-α-1 | 2017-09-17 | 构建Java JMod文件。 | 吉特/github | Jira MJMOD公司 |
报告插件 | 生成报告的插件在POM中配置为报告,并在站点生成生命周期中运行。 | |||||
变更日志 | R(右) | 2.3 | 2014-06-24 | 从SCM生成最近更改的列表。 | 吉特/github | 吉拉·麦昌格洛格 |
变化 | B+R | 2.12.1 | 2016-11-01 | 从问题跟踪器或更改文档生成报告。 | 吉特/github | 吉拉·麦钱斯 |
代码检查 | B+R | 3.3.0 | 2023-05-19 | 生成Checkstyle报告。 | 吉特/github | 吉拉·麦切克风格 |
多哈回合 | B类 | 1.2 | 2015-03-17 | 从POM生成项目描述(DOAP)文件。 | 吉特/github | 吉拉MDOAP |
文件 | B类 | 1.1 | 2015-04-03 | 文档检查器插件。 | 吉特/github | Jira MDOCCK公司 |
java文档 | B+R | 3.6.0 | 2023-09-11 | 为项目生成Javadoc。 | 吉特/github | 吉拉·玛卡瓦多克 |
jdeps公司 | B类 | 3.1.2 | 2019-06-12 | 在项目上运行JDK的JDeps工具。 | 吉特/github | Jira MJDEPS公司 |
jxr公司 | R(右) | 3.3.0 | 2022-08-16 | 生成源交叉引用。 | 吉特/github | 吉拉JXR |
链接检查 | R(右) | 1.2 | 2014-10-08 | 生成项目文档的Linkcheck报告。 | 吉特/github | 吉拉·姆林切克 |
偏振模色散 | B+R | 3.21.0 | 2023-05-12 | 生成PMD报告。 | 吉特/github | 吉拉MPMD |
报告中的项目 | R(右) | 3.4.5 | 2023-06-03 | 生成标准项目报告。 | 吉特/github | 吉拉MPIR |
可靠的报告 | R(右) | 3.1.2 | 2023-06-03 | 根据单元测试的结果生成报告。 | 吉特/github | Jira SUREFIRE公司 |
工具 | 默认情况下,这些是Maven提供的各种工具。 | |||||
安特伦 | B类 | 3.1.0 | 2022-04-18 | 从构建的一个阶段运行一组ant任务。 | 吉特/github | 吉拉·曼特伦 |
人工制品 | B类 | 3.5.0 | 2023-10-02 | 管理工件任务,如buildinfo。 | 吉特/github | 吉拉·马蒂法特 |
原型 | B类 | 3.2.1 | 2021-12-30 | 从原型生成一个框架项目结构。 | 吉特/github | Jira建筑类型 |
装配 | B类 | 3.6.0 | 2023-05-11 | 构建源代码和/或二进制文件的程序集(分发版)。 | 吉特/github | 吉拉·马斯塞姆利 |
附属国 | B+R | 3.6.0 | 2023-05-19 | 相关性操作(复制、解压缩)和分析。 | 吉特/github | 吉拉MDEP |
强制执行人 | B类 | 3.4.1 | 2023-09-07 | 环境约束检查(Maven版本、JDK等)、用户自定义规则执行。 | 吉特/github | 吉拉·曼福塞 |
gpg(加仑/加仑) | B类 | 3.1.0 | 2023-05-06 | 为工件和pom创建签名。 | 吉特/github | 吉拉MGPG |
帮助 | B类 | 3.4.0 | 2023-03-14 | 获取有关项目工作环境的信息。 | 吉特/github | 吉拉公共卫生部 |
调用程序 | B+R | 3.6.0 | 2023-06-11 | 运行一组Maven项目并验证输出。 | 吉特/github | 吉拉·明沃克 |
震击者 | B类 | 3.0.0 | 2018-11-06 | 签署或验证项目工件。 | 吉特/github | Jira MJAR签名人 |
jderscan扫描 | B类 | 3.0.0-α-1 | 2017-11-15 | 在项目上运行JDK的JDeprScan工具。 | 吉特/github | 吉拉·梅杰普斯卡纳 |
补丁 | B类 | 1.2 | 2015-03-09 | 使用gnu补丁工具将补丁文件应用于源代码。 | 吉特/github | 吉拉·马奇 |
pdf格式 | B类 | 1.6.1 | 2022-08-16 | 生成项目文档的PDF版本。 | 吉特/github | 吉拉MPDF |
插件 | B类 | 3.9.0 | 2023-05-12 | 为源代码树中的任何mojo创建Maven插件描述符,以包含在JAR中。 | 吉特/github | 吉拉·穆卢金 |
插件报告 | R(右) | 3.9.0 | 2023-05-12 | 为源代码树中的任何mojo创建插件文档。 | 吉特/github | 吉拉·姆卢金 |
释放 | B类 | 3.0.1 | 2023-05-30 | 发布当前项目-在SCM中更新POM和标记。 | 吉特/github | 吉拉·梅勒莱斯 |
远程资源 | B类 | 3.1.0 | 2023-05-08 | 将远程资源复制到输出目录以包含在工件中。 | 吉特/github | Jira MRRESOURCES公司 |
供应链管理 | B类 | 2.0.1 | 2023-05-15 | 对当前项目执行SCM命令。 | 吉特/github | Jira供应链管理 |
scm发布 | B类 | 3.2.1 | 2023-03-26 | 将Maven网站发布到scm位置。 | 吉特/github | 吉拉MSCMPUB |
编写脚本 | B类 | 3.0.0 | 2021-03-01 | Maven脚本插件根据JSR223封装了脚本API。 | 吉特/github | Jira MSCRIPTING公司 |
阶段 | B类 | 1 | 2015-03-03 | 协助发布阶段和推广。 | 吉特/github | Jira MSTAGE公司 |
工具链 | B类 | 3.1.0 | 2022-06-18 | 允许跨插件共享配置。 | 吉特/github | 吉拉·姆托卡恩斯 |
包装器 | B类 | 3.2.0 | 2023-03-09 | 下载并解压缩maven包装器发行版 | 吉特/github | 吉拉·姆夫拉珀 |
*B类uild或R(右)报告插件
我们还提供了一些沙盒插件源存储库.
插件参考文档的先前存档版本包括位于此处.
提供最佳实践开发指南
Maven 旨在收集最佳实践开发的当前原则,并轻松引导项目朝该方向发展。
例如,单元测试的规范、执行和报告是使用 Maven 的正常构建周期的一部分。当前的单元测试最佳实践被用作指导方针:
- 将测试源代码保存在单独但并行的源代码树中
- 使用测试用例命名约定来定位和执行测试
- 让测试用例设置其环境,而不是定制测试准备的构建
Maven 还协助项目工作流程,例如发布和问题管理。
Maven 还建议了一些关于如何布局项目目录结构的指南。一旦了解了布局,您就可以轻松导航使用 Maven 的其他项目。
虽然 Maven 对项目布局采取了固执己见的方法,但由于历史原因,某些项目可能不适合这种结构。虽然 Maven 被设计为能够灵活地满足不同项目的需求,但它无法在不影响其目标的情况下满足所有情况。
如果您的项目具有无法重组的不寻常构建结构,您可能必须放弃某些功能或完全放弃 Maven 的使用。
Maven的核心特性
-
标准化的项目结构
- Maven要求项目遵循一种标准的目录结构,例如:
src/main/java # 源代码 src/main/resources # 资源文件 src/test/java # 测试代码 src/test/resources # 测试资源文件 pom.xml # 项目描述文件
- 这种标准化的结构使得开发者可以快速理解和导航项目结构,减少了项目间因为目录结构不一致带来的困扰。
- Maven要求项目遵循一种标准的目录结构,例如:
-
依赖管理
- Maven通过
pom.xml
文件声明项目依赖,自动完成依赖的下载、安装和管理。 - 支持依赖的范围(
scope
)管理,如compile
(编译范围,默认)、test
(测试范围)、runtime
(运行时范围)等,方便管理不同阶段所需的依赖。 - 支持依赖的传递性,即如果项目A依赖于项目B,而项目B又依赖于项目C,Maven会自动将项目C的依赖包含进项目A的依赖中。
- 提供依赖冲突解决机制,通过策略(如“最近的者优先”)解决依赖版本冲突的问题。
- Maven通过
-
构建生命周期
- Maven定义了一个标准化的构建生命周期,包括以下几个主要阶段:
validate
: 验证项目是否正确,并且所有必要的信息都可用。compile
: 编译项目的源代码。test
: 使用合适的单元测试框架(如JUnit)运行测试。package
: 将编译好的代码打包成可分发的格式,如JAR、WAR。verify
: 运行任何检查来验证构建输出是否满足要求。install
: 将包安装到本地仓库,以便可以作为其他本地项目的依赖。deploy
: 将最终的包发送到远程仓库,供其他开发者或项目使用。
-
maven常用命令
-
mvn clean 清理,编译后的目录;
-
mvn compile 编译;只编译main目录,不编译test中代码;
-
mvn test-compile 编译test麻目录中代码;
-
mvn test 运行test里边代码测试;
-
web项目打成war包
-
mvn install 发布项目到本地仓库,在本地Repository中安装jar,供其他工程使用;
-
tomcat run 一键构建项目
-
mvn site 生成项目的相关文档和生成文档相关的元素,包括name,url,和description等。
-
- Maven定义了一个标准化的构建生命周期,包括以下几个主要阶段:
-
插件体系
- Maven的功能主要通过插件来实现,如
maven-compiler-plugin
用于编译代码,maven-surefire-plugin
用于执行测试,maven-source-plugin
用于生成源代码包等。 - 用户可以通过配置插件,自定义构建过程,例如定义自定义的编译选项、测试配置等。
- Maven的功能主要通过插件来实现,如
-
项目继承与多模块管理
- Maven支持项目继承,一个父项目可以定义多个子项目,子项目继承父项目的依赖和插件配置,简化了项目间的配置管理。
- 在多模块项目中,可以通过
modules
元素定义子模块,Maven允许对子模块进行统一的构建和管理。
Maven的分模块设计
-
多模块项目的结构
- 多模块项目包含一个父项目和多个子项目,项目结构如下:
parent-project/ ├── pom.xml # 父项目的POM文件 └── module-A/ ├── src/ # 模块A的源代码 └── pom.xml # 模块A的POM文件
- 父项目的
pom.xml
文件中使用<modules>
元素声明子模块:<modules> <module>module-A</module> </modules>
- 多模块项目包含一个父项目和多个子项目,项目结构如下:
-
分模块设计的优势
- 职责分离:将大型项目划分为多个独立的模块,每个模块负责不同的功能,提高代码的可维护性和复用性。
- 独立管理:每个模块可以有自己的依赖和配置,彼此之间互不干扰。
- 统一构建:通过Maven的多模块管理,可以对所有模块进行统一的构建、测试和打包,简化了多模块项目的管理。
- 资源共享:模块之间可以共享父项目中的依赖和插件配置,减少重复的配置工作。
-
实现细节
- 在多模块项目中,子模块的
pom.xml
文件继承父项目的groupId
和version
,通过<parent>
元素声明父项目:<parent> <groupId>com.example.parent</groupId> <artifactId>parent-project</artifactId> <version>1.0.0-SNAPSHOT</version> </parent>
- 子模块可以定义自己独有的依赖和插件,父项目则定义所有模块共享的依赖和插件。
- 在多模块项目中,子模块的
Maven的注意事项
-
合理管理依赖
- 避免过多的依赖:尽量减少不必要的依赖,避免“依赖地狱”。
- 统一依赖版本:通过父项目或依赖管理部分统一管理依赖版本,避免子模块间的依赖冲突。
- 定期清理依赖:通过Maven的
dependency:analyze
插件,分析项目中的未使用依赖,并对其进行清理。
-
配置插件时注意配置正确性
- 仔细阅读插件文档:在配置插件时,确保理解插件的功能和配置参数,避免由于配置错误导致的构建失败。
- 避免过度自定义:尽量使用Maven的默认配置和生命周期,减少不必要的自定义配置,提高项目的可维护性。
-
注意仓库管理
- 使用高速镜像仓库:配置Maven使用较快的仓库镜像,如Nexus、Alibaba’s public repository,提高依赖下载速度。
- 管理本地仓库:定期清理本地仓库,避免旧版本的依赖占用过多磁盘空间,影响构建性能。
-
多模块项目需要合理设计
- 模块划分合理:根据功能需求,将项目划分为独立的模块,避免模块之间过于紧密耦合。
- 减少模块间的依赖循环:确保模块之间不出现循环依赖,通过层次化的模块结构,合理规划依赖关系。
-
及时更新与维护
- 及时更新Maven和插件版本:定期更新Maven和插件到最新版本,获取新功能和性能改进。
- 关注项目更新与变化:对于长期维护的项目,需要定期审查和更新项目的依赖和配置,确保项目的健康和安全。
-
使用Maven的有效实践
- 遵循Maven的最佳实践:如遵循标准的目录结构、合理管理依赖范围、利用Maven的生命周期扩展功能等。
- 利用IDE的Maven集成工具:现代IDE如Eclipse、IntelliJ IDEA等都对Maven提供了良好的集成支持,可以通过IDE的图形界面简化Maven项目的管理和构建。