Maven 快速入门
- 一、简介
- 1、概述
- 2、特点
- 3、工作原理
- 4、常用命令
- 5、生命周期
- 6、优缺点
- 🎈 面试题
- 二、安装和配置
- 1、安装
- 2、环境配置
- 3、命令测试是否安装成功
- 4、功能配置
- 5、idea配置本地 maven
- 6、maven 工程依赖包查询网站
- 三、基于IDEA创建Maven工程
- 1、maven 工程中的 GAVP
- 2、idea 创建 maven 的 Java 工程
- 3、idea 创建 maven 的 web 工程
- 方式一:手动创建
- 方式二:插件创建
- 4、将 maven 的 web 工程 部署到 tomcat 中
- 5、Maven 标准目录结构
- 四、基于IDEA进行Maven工程构建
- 方式一:命令方式项目构建
- (1)编译、清理
- (2)测试、报告
- (3)打包、安装
- 方式二:可视化方式项目构建
- 五、基于IDEA进行Maven依赖管理
- 1、依赖管理概述
- 2、Maven 依赖范围
- 3、Maven 工程依赖下载失败问题解决方法
- 4、Maven 工程 Build 构建配置
- 六、Maven依赖传递和依赖冲突
- 1、依赖传递的规则
- 2、Maven自动解决依赖冲突规则
- 3、手动解决依赖冲突
- 七、Maven工程继承和聚合关系
- 1、继承
- 2、聚合
- 3、maven 多模块构建综合案例
一、简介
1、概述
Maven
是一个基于项目对象模型
(POM,Project Object Model)的开源构建工具,主要用于Java
项目。它不仅可以 帮助开发者管理项目的构建
、依赖管理
,还能用于测试
、打包
和部署
等任务。Maven 的核心思想
是将项目的所有信息,包括依赖关系、构建过程和插件配置等,都放在一个名为pom.xml
的文件中。这个文件描述了项目的基本信息
、依赖关系
、构建命令
等。
2、特点
-
依赖管理:Maven 可以
自动下载和管理项目的所有依赖库
,避免手动下载和管理JAR
文件。通过pom.xml
中指定的依赖项,Maven
会从中央仓库或者自定义仓库中自动下载这些库并将它们引入项目。 -
生命周期管理:
Maven
的生命周期
包括几个阶段,比如compile(编译)
、test(测试)
、package(打包)
、install(安装到本地仓库)
和deploy(部署到远程仓库)
。你可以在命令行中通过mvn 命令
来执行这些操作。 -
插件机制:
Maven
提供了丰富的插件来扩展功能。例如,maven-compiler-plugin
用于编译Java
代码,maven-surefire-plugin
用于运行测试,maven-jar-plugin
用于打包项目等。通过插件,Maven
可以执行几乎所有的构建相关任务。 -
仓库机制:
Maven
中的依赖库可以从远程仓库
(比如Maven 中央仓库
)获取,也可以存储在本地仓库
中。开发者还可以设置公司内部的私有仓库,用于管理特定的私有组件。
3、工作原理
pom.xml
文件:这是Maven
项目的核心配置文件,包含了项目的信息
、依赖关系
、构建插件和配置
。每个Maven
项目都有一个pom.xml
,该文件会递归解析父子关系的pom.xml
文件,形成最终的构建配置。- 仓库管理:
Maven
中的依赖是通过Maven
仓库管理的,中央仓库是Maven
默认的仓库,除此之外还可以配置企业的私有仓库。Maven
会首先检查本地仓库中是否已经存在依赖,如果没有则会去远程仓库中下载。
4、常用命令
mvn clean
: 删除编译生成的所有文件。mvn compile
: 编译项目。mvn test
: 运行项目中的测试。mvn package
: 打包项目(例如将项目打包成一个 JAR 文件)。mvn install
: 将项目的打包结果安装到本地 Maven 仓库。mvn deploy
: 将项目部署到远程仓库。mvn site
:建立和发布项目站点
5、生命周期
clean
生命周期:清理项目default
生命周期:构建项目site
生命周期:建立和发布项目站点
6、优缺点
优点
:
- 简化了项目依赖管理,易于上手;
- 便于功能扩展和项目升级,有助于多模块项目的开发;
缺点
:
maven
是一个庞大的构建系统,学习难度大;maven
采用约定优于配置的策略,虽然上手容易,但是一旦出了问题,难于调试。- 中国的网络环境差,很多
repository
无法访问,比如google code
,jboss 仓库
无法访问等。
🎈 面试题
1.
Maven 规约
:
/src/main/java/
:Java 源码。/src/main/resource
:Java 配置文件,资源文件。/src/test/java/
:Java 测试代码。/src/test/resource
:Java 测试配置文件,资源文件。/target
:文件编译过程中生成的.class
文件、jar
、war
等等。pom.xml
:配置文件
2.
对于一个多模块项目,如何管理项目依赖的版本
:
- 通过在
父模块
中声明dependencyManagement
和pluginManagement
, 然后让子模块
通过<parent>
元素指定父模块
,这样子模块
在定义依赖是就可以只定义groupId
和artifactId
,自动使用父模块
的version
,这样统一整个项目的依赖的版本。
3.
多模块如何聚合
:
- 配置一个打包类型为
pom
的聚合模块,然后在该pom
中使用<module>
元素声明要聚合的模块
4.
常见的 Maven 私服的仓库类型
:
- (
宿主仓库
)hosted repository- (
代理仓库
)proxy repository- (
仓库组
)group repository
5.
解决依赖冲突
:
- 使用
<exclusions>
标签排除依赖传递
二、安装和配置
1、安装
maven 版本下载
工具 | 版本 |
---|---|
IDEA | 2024.1.3 |
JDK | 17 |
MAVEN | 3.8.8 |
-
安装条件:
maven
需要本机安装Java
环境,必须包含Java_home
环境变量。 -
软件下载:
-
软件安装:免安装,解压到指定目录即可
-
软件结构:
-
bin 文件夹:用来执行
Maven 命令
的地方 -
boot 文件夹:包含用于启动
Maven
时加载的类和资源。它的作用是加载Maven
的必要组件和启动环境。 -
conf 文件夹:这个目录存放
Maven
的 全局配置文件settings.xml
文件。该文件用于配置 Maven 的行为,例如代理设置、本地仓库位置等。 -
lib 文件夹:这个目录中存放了
Maven
运行所需的所有依赖库,包括Maven 核心库
、插件库
等。 -
LICENSE 文件:这是
Maven
软件的开源许可证文件,通常是Apache License 2.0
,用户可以查看Maven
的许可条款。 -
NOTICE 文件:该文件列出了
Maven
依赖的开源项目和相关版权信息,通常会提到使用了哪些第三方库或工具。 -
README.txt 文件:提供关于
Maven
的基础说明和使用指南,一般是一些简短的说明文档,帮助用户快速上手。
2、环境配置
-
配置 MAVEN_HOME
-
配置环境变量 PATH
3、命令测试是否安装成功
mvn -v: 查看
maven
安装版本
4、功能配置
修改
conf\settings.xml
配置文件中以下内容
1. 本地仓库位置
<localRepository>自己设置的地址</localRepository>
2. maven
国内阿里镜像网站
<mirror><id>alimaven</id><name>aliyun maven</name><url>https://maven.aliyun.com/repository/public/</url><mirrorOf>central</mirrorOf></mirror>
3. maven
选用编译项目的jdk
版本
<profile><id>jdk-17</id><activation><activeByDefault>true</activeByDefault><jdk>17</jdk></activation><properties><maven.compiler.source>17</maven.compiler.source><maven.compiler.target>17</maven.compiler.target><maven.compiler.compilerVersion>17</maven.compiler.compilerVersion></properties></profile>
5、idea配置本地 maven
6、maven 工程依赖包查询网站
maven 工程依赖包查询网站
三、基于IDEA创建Maven工程
1、maven 工程中的 GAVP
在
Maven
项目中,GAVP
是指项目的四个核心概念,用于唯一标识Maven
工程及其构件。
GroupId
确定项目的组织归属。
<!--一个 GroupId 可以包含多个项目-->
<groupId>com.example.myproject</groupId>
ArtifactId
确定项目或模块的名称。
<!--每个项目或模块都有唯一的 ArtifactId,并且在相同的 GroupId 下,ArtifactId 必须唯一-->
<artifactId>my-app</artifactId>
Version
确定项目的版本信息。
<!--
SNAPSHOT:代表未正式发布的开发版本
Release:代表已发布的稳定版本
例如:
1.0.0-SNAPSHOT 表示开发中的版本;
1.0.0 表示正式发布的稳定版本。
-->
<version>1.0.0</version>
Packaging
确定项目的打包方式。
<packaging>jar</packaging>
常见的
packaging
类型:
jar
:默认值,标准的Java
类库,代表普通Java工程,打包后以.jar
结尾。war
:用于Web
应用,代表web
工程, 打包后以.war
结尾。pom
:不会打包,仅包含pom.xml
配置文件的聚合项目(表示该项目是一个聚合项目,用来管理其他模块),用于做继承的父工程。
综合示例:
一个完整的Maven
工程POM
文件中的GAVP
信息可能如下:
<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.example.myproject</groupId><artifactId>my-app</artifactId><version>1.0.0-SNAPSHOT</version><packaging>jar</packaging><!-- 其他配置... -->
</project>
注意:
继承与聚合项目
:在多模块项目中,父项目的 packaging
通常是 pom
,并且父项目可以管理子模块的 GroupId
和 Version
,子模块通常只需定义 ArtifactId
。
2、idea 创建 maven 的 Java 工程
创建完成之后效果:
3、idea 创建 maven 的 web 工程
方式一:手动创建
- 创建一个
maven
的Javase
工程- 修改
pom.xml
文件的打包方式- 设置
web
资源路径和web.xml
路径
方式二:插件创建
- 安装插件:
JavaToWeb
- 创建一个
maven
的Javase
工程- 设置
web
资源路径和web.xml
路径
4、将 maven 的 web 工程 部署到 tomcat 中
5、Maven 标准目录结构
my-maven-project/
│
├── pom.xml // Maven 项目核心配置文件
├── src/ // 源代码目录
│ ├── main/ // 项目主代码(包括 Java、资源等)
│ │ ├── java/ // Java 源代码
│ │ ├── resources/ // 项目资源文件(配置文件等)
│ │ ├── filters/ // 资源文件过滤器
│ │ └── webapp/ // Web 项目的 web 资源(如 HTML、CSS)
│ │
│ ├── test/ // 测试代码(包括 Java 测试和资源等)
│ │ ├── java/ // 测试用例的 Java 源代码
│ │ ├── resources/ // 测试用例所需的资源文件
│ │ └── filters/ // 测试资源文件过滤器
│
└── target/ // Maven 编译和打包生成的文件(如 class、jar 等)└── *.jar // 打包生成的 JAR 文件或 WAR 文件
四、基于IDEA进行Maven工程构建
方式一:命令方式项目构建
(1)编译、清理
mvn clean
:清理
mvn compile
:编译
maven_java
工程下编写一个Java
类pom.xml
文件中引入lombok
依赖pom.xml
文件目录下打开命令窗口,执行maven
命令
(2)测试、报告
mvn clean
:清理
mvn test-compile
:编译测试类
mvn test
:测试
mvn clean test
:清理后直接测试,并生成测试报告surefire-reports
文件夹
maven_java
工程下编写一个Java
测试类pom.xml
文件中引入junit
依赖pom.xml
文件目录下打开命令窗口,执行maven
命令
(3)打包、安装
mvn package
:打包
- 最终打成的无论是
jar
包还是war
包,里面是不包含测试代码
的,只有核心功能代码
,因为测试是打包之前的操作,既然能打包成功,说明测试没有问题
打包
和安装
区别:
打包
是将工程打成jar包
或war包
文件,并保存到target
目录下安装
是将工程打包生成的jar包
或war包
文件安装到本地仓库
,会按照坐标保存到指定位置
安装示例
- 假如 有
maven_java
、maven_web
两个maven
工程,maven_web
工程要依赖使用maven_java
工程,要按照以下步骤:
- 首先将打成的
maven_java
工程jar包
安装到本地仓库
;- 然后在
maven_web
工程的pom.xml
文件中引入maven_java
工程坐标,否则maven_web
工程无法找到依赖,无法打包- 打包
maven_web
工程
安装:
方式二:可视化方式项目构建
maven_java
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.ningxia.maven</groupId><artifactId>maven_java</artifactId><version>1.0-SNAPSHOT</version><properties><maven.compiler.source>17</maven.compiler.source><maven.compiler.target>17</maven.compiler.target><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding></properties><dependencies><!-- https://mvnrepository.com/artifact/org.projectlombok/lombok --><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><version>1.18.24</version><scope>provided</scope></dependency><!-- https://mvnrepository.com/artifact/org.junit.jupiter/junit-jupiter-api --><dependency><groupId>org.junit.jupiter</groupId><artifactId>junit-jupiter-api</artifactId><version>5.9.2</version><scope>test</scope></dependency></dependencies>
</project>
maven_web
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.ningxia.maven</groupId><artifactId>maven_web</artifactId><version>1.0-SNAPSHOT</version><packaging>war</packaging><properties><maven.compiler.source>17</maven.compiler.source><maven.compiler.target>17</maven.compiler.target><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding></properties><build><plugins><!-- jdk 17 和 war包版本不匹配 --><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-war-plugin</artifactId><version>3.2.2</version></plugin></plugins></build><dependencies><dependency><groupId>com.ningxia.maven</groupId><artifactId>maven_java</artifactId><version>1.0-SNAPSHOT</version></dependency></dependencies></project>
五、基于IDEA进行Maven依赖管理
1、依赖管理概述
1. 依赖管理: 通过定义项目所需要的库,自动下载和管理这些库,避免手动配置的繁琐。
2.Maven
工程核心信息配置和解读 (GAVP
):每个Maven
项目都通过其核心信息配置GAVP(Group ID、Artifact ID、Version、Packaging)
这四个信息来唯一标识和管理。
3.Maven
工程依赖管理配置:pom.xml
文件中定义项目所需的依赖,如何添加第三方库等。
4. 依赖范围:Maven
中的依赖范围(Scope
),如compile
、provided
、runtime
、test
和system
,这些范围决定了依赖在编译
、运行
时等不同阶段的可见性和作用。
5. Maven 工程依赖下载失败情境错误解决 (重点): 讨论在 Maven 下载依赖时可能会遇到的错误,以及如何处理这些错误,尤其是如何解决依赖下载失败的问题。这部分是重点,可能会涉及网络配置、仓库设置、依赖版本冲突等常见问题的解决办法。
6. Maven 工程 Build 构建配置: 这一部分会介绍如何配置和管理 Maven 工程的构建过程。主要包括构建生命周期(build lifecycle)、构建阶段(build phases)和插件的使用等,确保项目能够成功打包、测试和部署。
2、Maven 依赖范围
Maven
的依赖范围(Scope
)用于控制项目中依赖库在不同阶段(编译、测试、运行
等)的可见性和可用性。通过设置依赖范围,可以有效管理依赖的使用场景,减少不必要的依赖包,提高项目构建效率。以下是Maven
中常见的几种依赖范围:
3、Maven 工程依赖下载失败问题解决方法
1. 网络问题导致依赖下载失败
- 检查网络连接:确保本地计算机能够正常访问互联网;
- 更换仓库地址:如果
Maven
仓库(如Maven Central
)不可用,可以在pom.xml
或settings.xml
中指定其他可用的镜像仓库
:如:阿里云
2. 依赖库版本冲突:
Maven
项目中可能引入了不同版本的同一个依赖库,导致下载失败或构建错误。
- 使用
mvn dependency:tree
命令:查看依赖树,找到版本冲突的依赖库。- 排除冲突的依赖:在
pom.xml
文件中,通过<exclusions>
标签排除 排除 的或不需要的依赖版本:
<dependency><groupId>com.example</groupId><artifactId>example-lib</artifactId><version>1.0</version><exclusions><exclusion><groupId>com.other</groupId><artifactId>conflict-lib</artifactId></exclusion></exclusions>
</dependency>
3.本地
Maven
仓库存储问题
- 根据报错的依赖坐标
GAV
直接定位到本地仓库,手动删除整个依赖文件夹,然后重新下载
4、Maven 工程 Build 构建配置
1. 指定构建资源文件的名称,非默认名称:
- 默认情况下,Maven在压缩项目时会生成一个
.jar
或.war
文件,并且文件名称通常是基于pom.xml
中指定的artifactId
和version
自动生成的,例如my-app-1.0-SNAPSHOT.jar
。- 通过自定义配置,可以为生成的资源文件指定不同的名称。例如,如果你想要一个简洁的名称或者特定格式的文件名,可以在中
pom.xml
通过元素进行配置:
<build><finalName>custom-name</finalName>
</build>
2. 制定构建打包时,指定包含文件格式和排除文件::
- 构建过程中,可以根据需要指定哪些文件或目录应该
包含
在最终的备份文件中,哪些不包含
。例如,您可能希望备份时排除
某些临时文件或开发过程中使用
的工具文件。- 您可以通过
<includes>
和<excludes>
标签来配置资源时的文件包含和排除规则:
<build><resources><resource><directory>src/main/resources</directory><includes><include>**/*.properties</include></includes><excludes><exclude>**/*.xml</exclude></excludes></resource></resources>
</build>
以上配置会在备用时 只包含.properties
文件,而排除.xml
文件。
3. 配置插件:
在Maven
项目中,可以通过配置插件来增强项目的功能,比如:在pom.xml
中使用Tomcat Maven Plugin
将项目部署到Tomcat
容器中进行调试或运行。以下是配置Tomcat
插件的示例,并详细讲解如何使用它。
<build><plugins><plugin><groupId>org.apache.tomcat.maven</groupId><artifactId>tomcat7-maven-plugin</artifactId> <!-- 或 tomcat9-maven-plugin --><version>2.2</version><configuration><url>http://localhost:8080/manager/text</url> <!-- Tomcat 服务器管理URL --><server>TomcatServer</server> <!-- 在 settings.xml 中配置的认证ID --><path>/my-webapp</path> <!-- 部署时的项目访问路径 --><username>admin</username> <!-- Tomcat 用户名 --><password>admin-password</password> <!-- Tomcat 密码 --><uriEncoding>UTF-8</uriEncoding></configuration></plugin></plugins>
</build>
六、Maven依赖传递和依赖冲突
1、依赖传递的规则
假如
A
依赖B
,B
依赖C
,C
是否传递到A
,取决于B
依赖C
时使用的依赖范围以
及配置
。
-
B
依赖C
时使用compile
作用域:可以传递;使用 非compile(如: test 或 provided )
作用域:不可以传递
-
B
依赖C
时,如果配置了<optional>true</optional>
标签:不能传递到A
B的pom.xml如下:
-----------------------------------------
<dependencies><dependency><groupId>com.alibaba</groupId><artifactId>druid</artifactId><version>1.2.15</version><optional>true</optional></dependency>
</dependencies>
总结:
依赖传递终止:
1. 非 compile
作用域的依赖传递会终止
2. 使用 <optional>true</optional>
标签配置会中止传递
2、Maven自动解决依赖冲突规则
- 路径最短优先原则(
第一原则
) pom.xml
文件中声明顺序优先规则(第二原则
)子pom.xml
内声明的优先于父pom.xml
中的依赖
A
通过路径A -> B -> C -> D -> E -> X(0.0.1)
和路径A -> F -> X(0.0.2)
引入不同版本的依赖,Maven
会选择X-0.0.2
,因为通过F
的路径比通过B
的路径更短。- 当
路径长度相同
的情况下,Maven
会选择在pom.xml
中声明顺序靠前的依赖。
因为E在F之前声明,Maven会选择X-0.0.1版本。<dependencies><dependency><groupId>com.example</groupId><artifactId>E</artifactId><version>1.0.0</version></dependency><dependency><groupId>com.example</groupId><artifactId>F</artifactId><version>1.0.0</version></dependency>
</dependencies>
3、手动解决依赖冲突
- 排除依赖:你可以通过
<exclusions>
标签显式排除某些不需要的依赖,避免冲突。
通过这种方式,B项目中的X-1.0.jar不会被传递到A项目,避免冲突<dependencies><dependency><groupId>com.example</groupId><artifactId>B</artifactId><version>1.0.0</version><exclusions><exclusion><groupId>com.example</groupId><artifactId>X</artifactId></exclusion></exclusions></dependency>
</dependencies>
- 使用
dependencyManagement
统一管理依赖版本:在多模块项目中,使用dependencyManagement
可以统一管理依赖的版本号,确保各模块使用相同版本的依赖。
A项目可以强制所有子模块使用X-2.0.0版本,避免冲突<dependencyManagement><dependencies><dependency><groupId>com.example</groupId><artifactId>X</artifactId><version>2.0.0</version></dependency></dependencies>
</dependencyManagement>
七、Maven工程继承和聚合关系
1、继承
继承是
Maven
中用于共享配置的一种机制。通过继承,子项目
可以复用父项目
中定义的插件、依赖、配置项等。子项目
通过<parent>
标签指定要继承的父项目
父项目 pom.xml
:
<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.example</groupId><artifactId>parent-project</artifactId><version>1.0.0</version><packaging>pom</packaging><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter</artifactId><version>2.5.4</version></dependency></dependencies>
</project>
子项目pom.xml
:
在下面示例中,child-project继承了parent-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"><modelVersion>4.0.0</modelVersion><parent><groupId>com.example</groupId><artifactId>parent-project</artifactId><version>1.0.0</version></parent><artifactId>child-project</artifactId><!-- 可以覆盖或添加依赖 --><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId><version>2.5.4</version></dependency></dependencies>
</project>
2、聚合
聚合
是一种将多个模块组织在一起并通过一个父项目
统一管理它们的构建方式。
父项目
不需要是一个实际的执行项目,它只是一个容器项目,用于管理子模块
,只需要一个pom.xml
配置文件即可- 在
父项目
的pom.xml
文件中,通过<modules>
标签列出所有的子模块
。每个子模块
对应一个相对路径。- 运行
父项目
的mvn install
或mvn clean
等命令时,会梯度地构建所有子模块
。
下面的parent-project就是一个聚合项目,module1并且module2是它的子模块。
在执行mvn install时,module1并且module2会被自动构建。<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.example</groupId><artifactId>parent-project</artifactId><version>1.0.0</version><packaging>pom</packaging><modules><module>module1</module><module>module2</module></modules>
</project>
3、maven 多模块构建综合案例
项目结构
my-project (父模块)
│
├── my-common-module (公共模块)
│
├── my-module-a (子模块A)
│
├── my-module-b (子模块B)
│
└── my-module-c (子模块C)
父模块
my-project/pom.xml
<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.example</groupId><artifactId>my-project</artifactId><version>1.0.0</version><!-- 定义打包类型为 pom ,表示不会生成任何可执行的jar或war文件,而是一个容器管理和构建它的子模块。 --><packaging>pom</packaging><modules><module>my-common-module</module><module>my-module-a</module><module>my-module-b</module><module>my-module-c</module></modules><properties><java.version>17</java.version><spring.version>5.3.21</spring.version></properties><dependencyManagement><dependencies><dependency><groupId>org.springframework</groupId><artifactId>spring-context</artifactId><version>${spring.version}</version></dependency><dependency><groupId>com.fasterxml.jackson.core</groupId><artifactId>jackson-databind</artifactId><version>2.12.5</version></dependency></dependencies></dependencyManagement><build><plugins><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-compiler-plugin</artifactId><version>3.8.1</version><configuration><source>${java.version}</source><target>${java.version}</target></configuration></plugin></plugins></build>
</project>
公共模块
my-common-module/pom.xml
<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><parent><groupId>com.example</groupId><artifactId>my-project</artifactId><version>1.0.0</version><relativePath>../pom.xml</relativePath></parent><artifactId>my-common-module</artifactId><dependencies><!-- 公共模块中定义了常用的依赖 --><dependency><groupId>org.springframework</groupId><artifactId>spring-context</artifactId></dependency><dependency><groupId>com.fasterxml.jackson.core</groupId><artifactId>jackson-databind</artifactId></dependency></dependencies>
</project>
子模块 A
my-module-a/pom.xml
<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><parent><groupId>com.example</groupId><artifactId>my-project</artifactId><version>1.0.0</version><relativePath>../pom.xml</relativePath></parent><artifactId>my-module-a</artifactId><dependencies><!-- 依赖公共模块 --><dependency><groupId>com.example</groupId><artifactId>my-common-module</artifactId><version>1.0.0</version></dependency><!-- 子模块A独有的依赖 --><dependency><groupId>org.apache.commons</groupId><artifactId>commons-lang3</artifactId><version>3.12.0</version></dependency></dependencies>
</project>
子模块 B
my-module-b/pom.xml
<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><parent><groupId>com.example</groupId><artifactId>my-project</artifactId><version>1.0.0</version><relativePath>../pom.xml</relativePath></parent><artifactId>my-module-b</artifactId><dependencies><!-- 依赖公共模块 --><dependency><groupId>com.example</groupId><artifactId>my-common-module</artifactId><version>1.0.0</version></dependency><!-- 子模块B独有的依赖 --><dependency><groupId>org.apache.commons</groupId><artifactId>commons-io</artifactId><version>2.11.0</version></dependency></dependencies>
</project>
子模块 C
my-module-c/pom.xml
<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><parent><groupId>com.example</groupId><artifactId>my-project</artifactId><version>1.0.0</version><relativePath>../pom.xml</relativePath></parent><artifactId>my-module-c</artifactId><dependencies><!-- 依赖公共模块 --><dependency><groupId>com.example</groupId><artifactId>my-common-module</artifactId><version>1.0.0</version></dependency><!-- 子模块C的独有依赖与模块B存在依赖冲突 --><dependency><groupId>org.apache.commons</groupId><artifactId>commons-io</artifactId><version>2.10.0</version> <!-- 与my-module-b冲突的版本 --></dependency></dependencies><!-- 解决依赖冲突 --><dependencyManagement><dependencies><dependency><groupId>org.apache.commons</groupId><artifactId>commons-io</artifactId><version>2.11.0</version> <!-- 统一版本 --></dependency></dependencies></dependencyManagement>
</project>
<relativePath>../pom.xml</relativePath>
是Maven parent
元素中的一个配置,用来指定当前子模块
相对于父模块
的pom.xml
文件的相对路径。
示例
在下面这个结构中:
- 子模块
my-module-a
的pom.xml
文件位于my-project/my-module-a
目录下。- 父模块的
pom.xml
位于上一级目录my-project/pom.xml
。
因此,子模块
my-module-a/pom.xml
中的relativePath
使用../pom.xml
,表示相对my-module-a
目录,返回到上一级的my-project
目录并引用其中的pom.xml
。
my-project (父模块)
│
├── pom.xml (父模块的pom文件)
│
├── my-module-a (子模块A)
│ └── pom.xml
├── my-module-b (子模块B)
│ └── pom.xml
└── my-module-c (子模块C)└── pom.xml
默认行为:
如果不指定
<relativePath>
,Maven
默认会假定父模块的pom.xml
位于子模块目录的上一级,因此在常见的项目结构中,即使不写<relativePath>
,Maven
也能找到父模块。不过,如果父模块的pom.xml
不在默认位置,或者项目结构比较复杂时,显式指定relativePath
是有帮助的。