Maven 快速入门

Maven 快速入门

一、简介

1、概述

Maven 是一个基于项目对象模型(POM,Project Object Model)的开源构建工具,主要用于 Java 项目。它不仅可以 帮助开发者管理项目的构建依赖管理,还能用于测试打包部署 等任务 。Maven 的 核心思想 是将项目的所有信息,包括依赖关系、构建过程和插件配置等,都放在一个名为 pom.xml 的文件中 。这个文件描述了项目的基本信息依赖关系构建命令等。


2、特点

  1. 依赖管理 :Maven 可以自动下载和管理项目的所有依赖库,避免手动下载和管理 JAR 文件。通过 pom.xml 中指定的依赖项,Maven 会从中央仓库或者自定义仓库中自动下载这些库并将它们引入项目。

  2. 生命周期管理Maven生命周期包括几个阶段,比如 compile(编译)test(测试)package(打包)install(安装到本地仓库)deploy(部署到远程仓库)。你可以在命令行中通过 mvn 命令来执行这些操作。

  3. 插件机制Maven 提供了丰富的插件来扩展功能。例如,maven-compiler-plugin 用于编译 Java 代码,maven-surefire-plugin 用于运行测试,maven-jar-plugin 用于打包项目等。通过插件,Maven 可以执行几乎所有的构建相关任务。

  4. 仓库机制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、生命周期

  1. clean生命周期:清理项目
  2. default生命周期:构建项目
  3. site生命周期:建立和发布项目站点

6、优缺点

优点

  • 简化了项目依赖管理,易于上手;
  • 便于功能扩展和项目升级,有助于多模块项目的开发;

缺点

  • maven是一个庞大的构建系统,学习难度大;
  • maven采用约定优于配置的策略,虽然上手容易,但是一旦出了问题,难于调试。
  • 中国的网络环境差,很多repository无法访问,比如google codejboss 仓库无法访问等。

🎈 面试题

1. Maven 规约

  • /src/main/java/ :Java 源码。
  • /src/main/resource :Java 配置文件,资源文件。
  • /src/test/java/ :Java 测试代码。
  • /src/test/resource :Java 测试配置文件,资源文件。
  • /target:文件编译过程中生成的 .class 文件、jarwar 等等。
  • pom.xml :配置文件

2. 对于一个多模块项目,如何管理项目依赖的版本

  • 通过在父模块中声明dependencyManagementpluginManagement, 然后让子模块通过<parent>元素指定父模块,这样子模块在定义依赖是就可以只定义groupIdartifactId,自动使用父模块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. 本地仓库位置

xml 复制代码
<localRepository>自己设置的地址</localRepository>

2. maven国内阿里镜像网站

xml 复制代码
    <mirror>
      <id>alimaven</id>
      <name>aliyun maven</name>
      <url>https://maven.aliyun.com/repository/public/</url>
	  <mirrorOf>central</mirrorOf>
    </mirror>

3. maven选用编译项目的jdk版本

xml 复制代码
	<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 确定项目的组织归属。
xml 复制代码
<!--一个 GroupId 可以包含多个项目-->
<groupId>com.example.myproject</groupId>
  • ArtifactId 确定项目或模块的名称。
xml 复制代码
<!--每个项目或模块都有唯一的 ArtifactId,并且在相同的 GroupId 下,ArtifactId 必须唯一-->
<artifactId>my-app</artifactId>
  • Version 确定项目的版本信息。
xml 复制代码
<!--
SNAPSHOT:代表未正式发布的开发版本
Release:代表已发布的稳定版本
例如:
1.0.0-SNAPSHOT 表示开发中的版本;
1.0.0 表示正式发布的稳定版本。
-->
<version>1.0.0</version>
  • Packaging 确定项目的打包方式。
xml 复制代码
<packaging>jar</packaging>

常见的 packaging 类型:

  • jar:默认值,标准的 Java 类库,代表普通Java工程,打包后以 .jar 结尾。
  • war:用于 Web 应用,代表 web工程, 打包后以 .war 结尾。
  • pom:不会打包,仅包含 pom.xml 配置文件的聚合项目(表示该项目是一个聚合项目,用来管理其他模块),用于做继承的父工程。

综合示例:

一个完整的 Maven 工程 POM文件中的 GAVP 信息可能如下:

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.myproject</groupId>
    <artifactId>my-app</artifactId>
    <version>1.0.0-SNAPSHOT</version>
    <packaging>jar</packaging>
    <!-- 其他配置... -->
</project>

注意:
继承与聚合项目 :在多模块项目中,父项目的 packaging 通常是 pom,并且父项目可以管理子模块的 GroupIdVersion,子模块通常只需定义 ArtifactId


2、idea 创建 maven 的 Java 工程


创建完成之后效果:

3、idea 创建 maven 的 web 工程

方式一:手动创建

  1. 创建一个mavenJavase工程
  2. 修改pom.xml文件的打包方式
  3. 设置web资源路径和web.xml路径



方式二:插件创建

  1. 安装插件: JavaToWeb
  2. 创建一个mavenJavase工程
  3. 设置web资源路径和web.xml路径




4、将 maven 的 web 工程 部署到 tomcat 中




5、Maven 标准目录结构

less 复制代码
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:编译

  1. maven_java工程下编写一个Java
  2. pom.xml文件中引入 lombok 依赖
  3. pom.xml文件目录下打开命令窗口,执行maven命令






(2)测试、报告

mvn clean:清理
mvn test-compile:编译测试类
mvn test:测试
mvn clean test:清理后直接测试,并生成测试报告 surefire-reports 文件夹

  1. maven_java工程下编写一个Java 测试类
  2. pom.xml文件中引入 junit 依赖
  3. pom.xml文件目录下打开命令窗口,执行maven命令




(3)打包、安装

mvn package:打包

  • 最终打成的无论是jar包还是war包,里面是不包含 测试代码的,只有核心功能代码,因为测试是打包之前的操作,既然能打包成功,说明测试没有问题

打包安装区别:

  • 打包是将工程打成 jar包war包文件,并保存到 target 目录下

  • 安装是将工程打包生成的 jar包war包文件安装到本地仓库,会按照坐标保存到指定位置
    安装示例

  • 假如 有 maven_javamaven_web 两个 maven 工程,maven_web 工程要依赖使用 maven_java 工程,要按照以下步骤:

  1. 首先将打成的 maven_java 工程 jar包安装到本地仓库
  2. 然后在 maven_web工程的 pom.xml 文件中引入 maven_java 工程坐标,否则maven_web工程无法找到依赖,无法打包
  3. 打包 maven_web工程



安装





方式二:可视化方式项目构建



maven_java pom.xml

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 复制代码
<?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),如 compileprovidedruntimetestsystem,这些范围决定了依赖在编译运行时等不同阶段的可见性和作用。

5. Maven 工程依赖下载失败情境错误解决 (重点): 讨论在 Maven 下载依赖时可能会遇到的错误,以及如何处理这些错误,尤其是如何解决依赖下载失败的问题。这部分是重点,可能会涉及网络配置、仓库设置、依赖版本冲突等常见问题的解决办法。

6. Maven 工程 Build 构建配置: 这一部分会介绍如何配置和管理 Maven 工程的构建过程。主要包括构建生命周期(build lifecycle)、构建阶段(build phases)和插件的使用等,确保项目能够成功打包、测试和部署。


2、Maven 依赖范围

Maven 的依赖范围(Scope)用于控制项目中依赖库在不同阶段(编译、测试、运行等)的可见性和可用性。通过设置依赖范围,可以有效管理依赖的使用场景,减少不必要的依赖包,提高项目构建效率。以下是 Maven 中常见的几种依赖范围:


3、Maven 工程依赖下载失败问题解决方法

1. 网络问题导致依赖下载失败

  • 检查网络连接:确保本地计算机能够正常访问互联网;
  • 更换仓库地址 :如果 Maven 仓库(如 Maven Central)不可用,可以在 pom.xmlsettings.xml 中指定其他可用的镜像仓库:如:阿里云

2. 依赖库版本冲突Maven 项目中可能引入了不同版本的同一个依赖库,导致下载失败或构建错误。

  • 使用mvn dependency:tree命令:查看依赖树,找到版本冲突的依赖库。
  • 排除冲突的依赖 :在pom.xml文件中,通过<exclusions>标签排除 排除 的或不需要的依赖版本:
xml 复制代码
<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中指定的artifactIdversion自动生成的,例如my-app-1.0-SNAPSHOT.jar
  • 通过自定义配置 ,可以为生成的资源文件指定不同的名称。例如,如果你想要一个简洁的名称或者特定格式的文件名,可以在中pom.xml通过元素进行配置:
xml 复制代码
<build>
  <finalName>custom-name</finalName>
</build>

2. 制定构建打包时,指定包含文件格式和排除文件::

  • 构建过程中,可以根据需要指定哪些文件或目录应该包含在最终的备份文件中,哪些不包含。例如,您可能希望备份时排除某些临时文件或开发过程中使用的工具文件。
  • 您可以通过 <includes><excludes> 标签来配置资源时的文件包含和排除规则:
xml 复制代码
<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 插件的示例,并详细讲解如何使用它。

xml 复制代码
<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 依赖 BB 依赖 CC 是否传递到 A,取决于 B 依赖 C 时使用的依赖范围以配置

    1. B依赖C时使用compile作用域:可以传递 ;使用 compile(如: test 或 provided )作用域:不可以传递
    1. B依赖C时,如果配置了<optional>true</optional> 标签:不能传递到A
xml 复制代码
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中声明顺序靠前的依赖。

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>标签显式排除某些不需要的依赖,避免冲突。
xml 复制代码
通过这种方式,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可以统一管理依赖的版本号,确保各模块使用相同版本的依赖。
xml 复制代码
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

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

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 installmvn clean等命令时,会梯度地构建所有子模块
xml 复制代码
下面的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 多模块构建综合案例

项目结构

xml 复制代码
my-project (父模块)
│
├── my-common-module (公共模块)
│
├── my-module-a (子模块A)
│
├── my-module-b (子模块B)
│
└── my-module-c (子模块C)

父模块 my-project/pom.xml

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

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

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

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

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-apom.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

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 是有帮助的。

相关推荐
juniperhan6 分钟前
Flink 系列第21篇:Flink SQL 函数与 UDF 全解读:类型推导、开发要点与 Module 扩展
java·大数据·数据仓库·分布式·sql·flink
ID_180079054737 分钟前
Python 实现亚马逊商品详情 API 数据准确性校验(极简可用 + JSON 参考)
java·python·json
c++之路27 分钟前
C++23概述
java·c++·c++23
专注API从业者1 小时前
Open Claw 京东商品监控选品实战:一键抓取、实时监控、高效选品
java·服务器·数据库
摇滚侠2 小时前
DBeaver 导入数据库 导入 SQL 文件 MySQL 备份恢复
java·数据库·mysql
keep one's resolveY2 小时前
SpringBoot实现重试机制的四种方案
java·spring boot·后端
天空属于哈夫克33 小时前
企业微信API常见的错误和解决方案
java·数据库·企业微信
摇滚侠3 小时前
VMvare 虚拟机 Oracle19c 安装步骤,远程连接 Oracle19c,百度网盘安装包
java·oracle
梁萌3 小时前
idea报错找不到XX包的解决方法
java·intellij-idea·启动报错·缺少包
Agent产品评测局4 小时前
生产排期与MES/ERP系统打通,实操方法详解 —— 2026企业级智能体自动化选型与实战指南
java·运维·人工智能·ai·chatgpt·自动化