Maven 全面解析:从概念到实战,包含 POM、BOM 的区别和应用

Maven 是 Java 生态中最主流的项目管理与自动化构建工具 ,由Apache基金会维护。它的核心价值在于解决传统Java项目的两大痛点:手动管理 Jar 包的混乱和构建流程的不统一,通过标准化的配置和命令,让开发者专注于代码逻辑而非项目运维。

目录

一、Maven 核心概念

Maven的三个核心组件:POM文件、仓库、生命周期与插件

1.POM文件:项目的"身份证"

POM(Project Object Model,项目对象模型)是Maven的核心,每个Maven项目目录下必有一个 pom.xml 文件,它定义了项目的基本信息、依赖、构建规则等所有配置。

核心标签解析

xml 复制代码
<?xml version="1.0" encoding="UTF-8"?>
<!-- Maven 模型版本,固定为 4.0.0 -->
<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>

    <!-- 项目唯一坐标(GAV):Maven 识别项目和依赖的核心 -->
    <groupId>com.example</groupId>   <!-- 组织/公司标识(如域名反写) -->
    <artifactId>maven-demo</artifactId> <!-- 项目/模块名称 -->
    <version>1.0-SNAPSHOT</version>  <!-- 版本号(SNAPSHOT 表示快照版,RELEASE 表示稳定版) -->
    <name>Maven Demo</name>           <!-- 项目名称(可选) -->
    <description>A simple Maven project</description> <!-- 项目描述(可选) -->

    <!-- 依赖管理:声明项目需要的 Jar 包 -->
    <dependencies>
        <!-- 示例1:引入 Spring Boot 核心依赖 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
            <version>2.7.10</version> <!-- 依赖版本号 -->
        </dependency>

        <!-- 示例2:引入 JUnit 测试依赖(仅测试阶段生效) -->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.13.2</version>
            <scope>test</scope> <!-- 依赖作用域,下文详解 -->
        </dependency>
    </dependencies>

    <!-- 构建配置:自定义编译、打包等流程 -->
    <build>
        <!-- 插件配置:Maven 核心功能由插件实现 -->
        <plugins>
            <!-- 示例:指定 Java 编译版本为 1.8 -->
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.8.1</version>
                <configuration>
                    <source>8</source> <!-- 源代码编译版本 -->
                    <target>8</target> <!-- 目标字节码版本 -->
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>

关键说明
GAV 坐标: groupId + artifactId + version 是Maven中唯一标识项目或依赖的"地址",Maven通过次坐标从仓库下载依赖

依赖作用域(scope):控制依赖在项目生命周期中的生效范围,常见值如下:

作用域(scope) 生效阶段 说明 示例
compile 编译、测试、运行(默认) 项目核心依赖,打包时会包含 Spring Core
test 仅测试阶段 测试用依赖,打包时不包含 JUnit、Mockito
provided 编译测试阶段 运行时由容器提供(如Tomcat),不打包 Servlet API
runtime 测试、运行阶段 编译时无需,运行时需要 MySQL驱动

2.仓库:依赖的"存储库"

Maven 依赖通过"仓库"获取,仓库分为三类,优先级从高到低为:本地仓库---远程仓库---中央仓库

复制代码
本地仓库:默认位于 C:\Users\用户名\.m2\repository(Windows)或
~/.m2/repository(Linux/Mac),是依赖本地缓存目录。首次下载的依赖会保存在这里,后续项目直接复用
远程仓库:企业/团队内部搭建的私有仓库(如
Nexus、Artifactory),用于存储内部开发的Jar包或缓存中央仓库的依赖,避免重复下载
中央仓库:Maven官方维护的公共仓库(https://repo.maven.apache.org/maven2),包含全球绝大多数开源Java依赖

配置远程仓库(示例:在pom.xml中添加Nexus仓库)

xml 复制代码
<repositories>
    <repository>
        <id>company-nexus</id> <!-- 仓库唯一标识 -->
        <name>Company Nexus Repository</name> <!-- 仓库名称 -->
        <url>http://192.168.1.100:8081/repository/maven-public/</url> <!-- 仓库地址 -->
        <releases>
            <enabled>true</enabled> <!-- 允许下载稳定版依赖 -->
        </releases>
        <snapshots>
            <enabled>true</enabled> <!-- 允许下载快照版依赖 -->
        </snapshots>
    </repository>
</repositories>

3.生命周期与插件:构建流程的"标准化"

Maven定义了一套标准化的项目生命周期,每个生命周期包含多个"阶段",开发者只需执行某个阶段的命令,Maven会自动执行该阶段之前的所有阶段

三大核心生命周期
clean生命周期: 清理项目编译生成的文件(如target目录)

复制代码
关键阶段:clean(删除 target)→ post-clean(清理后操作)

default 生命周期: 项目构建的核心流程(最常用)

复制代码
关键阶段:compile(编译源代码)→ test(执行测试)→ package(打包,如 Jar/War)→
install(安装到本地仓库)→ deploy(部署到远程仓库)

site 生命周期: 生成项目文档站点

复制代码
关键阶段:site(生成文档)→ site-deploy(部署文档到服务器)

插件:生命周期的 "执行者"

Maven 本身不实现具体构建逻辑,而是通过插件绑定到生命周期的阶段来执行任务。例如:

复制代码
maven-compiler-plugin:绑定到 compile 阶段,负责编译 Java 代码。
maven-surefire-plugin:绑定到 test 阶段,负责执行 JUnit 测试。
maven-jar-plugin:绑定到 package 阶段,负责将项目打包为 Jar 包。

二、Maven环境搭建

1.前置条件

复制代码
安装 JDK(Maven 3.8+ 要求 JDK 8+),并配置 JAVA_HOME 环境变量

2.下载安装 Maven

复制代码
1. 从 Apache 官网下载 Maven:https://maven.apache.org/download.cgi(选择 apache-maven-x.y.z-bin.zip)。 
2. 解压到本地目录(如 D:\apache-maven-3.9.6)。
3. 配置环境变量: 
新建 MAVEN_HOME:值为 Maven 解压目录(如 D:\apache-maven-3.9.6)。
编辑 PATH:添加 %MAVEN_HOME%\bin(Windows)或 ${MAVEN_HOME}/bin(Linux/Mac)。
4. 验证安装:打开命令行,执行 mvn -v,输出如下信息表示成功:
html 复制代码
Apache Maven 3.9.6 (bc0240f3c744dd6b6ec2920b3cd08dcc295161ae)
Maven home: D:\apache-maven-3.9.6
Java version: 1.8.0_381, vendor: Oracle Corporation, runtime: D:\jdk1.8.0_381\jre
Default locale: zh_CN, platform encoding: GBK
OS name: "windows 10", version: "10.0", arch: "amd64", family: "windows"

3.配置本地仓库与镜像

默认本地仓库路径可能占用 C 盘空间,可修改为自定义路径;同时,国内访问中央仓库速度慢,可配置阿里云镜像加速。

复制代码
打开 Maven 配置文件:MAVEN_HOME/conf/settings.xml。
修改本地仓库路径:
xml 复制代码
<localRepository>D:\maven-repository</localRepository>
复制代码
添加阿里云镜像(替换默认中央仓库):
xml 复制代码
<mirrors>
    <mirror>
        <id>aliyunmaven</id>
        <mirrorOf>central</mirrorOf> <!-- 匹配中央仓库 -->
        <name>阿里云公共仓库</name>
        <url>https://maven.aliyun.com/repository/public</url>
    </mirror>
</mirrors>

三、Maven 实战:常用操作与命令

1. 创建 Maven 项目

方式 1:命令行创建(快速生成模板项目)

执行以下命令,按提示输入 groupId、artifactId 等信息(直接回车使用默认值):

bash 复制代码
# 生成普通 Java 项目(archetype 为模板标识)
mvn archetype:generate -DgroupId=com.example -DartifactId=maven-demo -DarchetypeArtifactId=maven-archetype-quickstart -DinteractiveMode=false
复制代码
archetypeArtifactId=maven-archetype-quickstart:普通 Java 项目模板。
archetypeArtifactId=maven-archetype-webapp:Java Web 项目模板。

方式 2:IDE 创建(以 IntelliJ IDEA 为例)

复制代码
打开 IDEA → 新建项目 → 选择 Maven → 勾选 Create from archetype。 
选择模板(如 maven-archetype-quickstart)→ 输入 GAV 坐标 → 选择 Maven 配置(自动识别 MAVEN_HOME)→ 完成。

2.核心构建命令

Maven 命令格式:mvn [生命周期阶段/插件:目标],以下是最常用的命令:

命令 作用
mvn clean 执行 clean 生命周期,删除 target 目录(编译生成的文件)
mvn compile 编译源代码,生成的字节码存放在 target/classes 目录
mvn test 执行测试(需引入 JUnit 依赖),测试报告存放在 target/surefire-reports
mvn package 打包项目(生成 Jar/War 包),包文件存放在 target 目录
mvn install 将项目打包后安装到本地仓库,供其他本地项目依赖
mvn deploy 将项目打包后部署到远程仓库(需配置远程仓库地址)
mvn clean package 组合命令:先清理,再打包(常用)
mvn dependency:tree 查看项目依赖树(排查依赖冲突必备)
mvn dependency:analyze 分析依赖:检测未使用的依赖或缺失的依赖

示例:查看依赖树(解决冲突)

执行 mvn dependency:tree,输出如下结构(可快速定位依赖版本冲突):

html 复制代码
[INFO] com.example:maven-demo:jar:1.0-SNAPSHOT
[INFO] +- org.springframework.boot:spring-boot-starter:jar:2.7.10:compile
[INFO] |  +- org.springframework.boot:spring-boot:jar:2.7.10:compile
[INFO] |  |  +- org.springframework:spring-core:jar:5.3.27:compile
[INFO] |  |  |  \- org.springframework:spring-jcl:jar:5.3.27:compile
[INFO] |  |  \- org.springframework:spring-context:jar:5.3.27:compile
[INFO] |  +- org.springframework.boot:spring-boot-autoconfigure:jar:2.7.10:compile
[INFO] |  \- org.yaml:snakeyaml:jar:1.30:compile
[INFO] \- junit:junit:jar:4.13.2:test
[INFO]    \- org.hamcrest:hamcrest-core:jar:1.3:test

3.解决依赖冲突(实战场景)

依赖冲突是 Maven 项目中常见问题,例如:项目同时依赖 spring-core:5.3.27 和 spring-core:5.2.0,Maven 会按以下规则选择版本:

复制代码
路径最短原则:依赖层级越浅,优先级越高。 
声明优先原则:路径相同时,pom.xml 中先声明的依赖优先级高。 
强制指定原则:通过 <dependencyManagement> 强制锁定版本(推荐)。

示例:强制锁定依赖版本

在 pom.xml 中通过 统一管理依赖版本,子模块(若有)会继承此配置:

xml 复制代码
<dependencyManagement>
    <dependencies>
        <!-- 强制 Spring Core 版本为 5.3.27 -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-core</artifactId>
            <version>5.3.27</version>
        </dependency>
        <!-- 强制 MySQL 驱动版本为 8.0.32 -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.32</version>
        </dependency>
    </dependencies>
</dependencyManagement>

示例:排除冲突依赖

若某个依赖间接引入了冲突版本,可通过 排除:

xml 复制代码
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
    <version>2.7.10</version>
    <!-- 排除内置的 Tomcat 依赖(改用 Jetty) -->
    <exclusions>
        <exclusion>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-tomcat</artifactId>
        </exclusion>
    </exclusions>
</dependency>
<!-- 引入 Jetty 依赖 -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-jetty</artifactId>
    <version>2.7.10</version>
</dependency>

四、Maven 进阶:多模块项目

当项目规模较大时,可拆分为多个模块(如 api、service、dao),通过 Maven 实现模块聚合依赖继承,提升项目可维护性。

1.多模块项目结构

yaml 复制代码
parent-project (父项目,打包类型为 pom)
├── pom.xml (父 POM,统一管理依赖版本)
├── module-api (子模块:接口层,打包类型为 jar)
│   └── pom.xml
├── module-service (子模块:服务层,依赖 module-api)
│   └── pom.xml
└── module-dao (子模块:数据访问层,依赖 module-service)
    └── pom.xml

2.父项目 POM 配置(parent-project/pom.xml)

父项目打包类型必须为 pom,用于聚合子模块和管理依赖:

xml 复制代码
<project>
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.example</groupId>
    <artifactId>parent-project</artifactId>
    <version>1.0-SNAPSHOT</version>
    <packaging>pom</packaging> <!-- 父项目打包类型为 pom -->
    <name>Parent Project</name>

    <!-- 聚合子模块:声明所有子模块 -->
    <modules>
        <module>module-api</module>
        <module>module-service</module>
        <module>module-dao</module>
    </modules>

    <!-- 统一管理子模块依赖版本(子模块无需再声明 version) -->
    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>com.example</groupId>
                <artifactId>module-api</artifactId>
                <version>${project.version}</version> <!-- 继承父项目版本 -->
            </dependency>
            <dependency>
                <groupId>com.example</groupId>
                <artifactId>module-service</artifactId>
                <version>${project.version}</version>
            </dependency>
            <!-- 第三方依赖版本管理 -->
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter</artifactId>
                <version>2.7.10</version>
            </dependency>
        </dependencies>
    </dependencyManagement>
</project>

3.子模块 POM 配置(module-service/pom.xml)

子模块通过 继承父项目,无需重复声明依赖版本:

xml 复制代码
<project>
    <modelVersion>4.0.0</modelVersion>
    <!-- 继承父项目 -->
    <parent>
        <groupId>com.example</groupId>
        <artifactId>parent-project</artifactId>
        <version>1.0-SNAPSHOT</version>
        <relativePath>../pom.xml</relativePath> <!-- 父 POM 相对路径 -->
    </parent>

    <artifactId>module-service</artifactId> <!-- 子模块唯一标识 -->
    <name>Module Service</name>

    <!-- 依赖子模块(无需声明 version,继承父项目) -->
    <dependencies>
        <dependency>
            <groupId>com.example</groupId>
            <artifactId>module-api</artifactId>
        </dependency>
        <!-- 依赖第三方库(无需声明 version,父项目已管理) -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
        </dependency>
    </dependencies>
</project>

五、BOM 的定义和使用

在多模块项目(尤其是大型多模块项目跨项目协作场景 )中,BOM(Bill of Materials,物料清单)是非常常用的进阶工具 ------ 它的核心作用是统一管理依赖版本,解决多模块 / 多项目间的依赖版本冲突,同时简化依赖配置。

很多开发者会混淆「父 POM」和「BOM」,其实两者是互补关系:父 POM 侧重「模块聚合 + 依赖继承 + 构建配置」,而 BOM 侧重「纯版本管理」,更灵活、可复用性更强。下面结合多模块项目场景,详细讲解 BOM 的作用、使用方式和实战代码。

1.BOM的核心定位和核心价值

BOM 本质是一个特殊的 Maven 项目,其 pom.xml 满足两个条件:

复制代码
打包类型必须是 pom(仅用于版本声明,不包含代码和资源); 
只包含 <dependencyManagement> 节点(声明依赖版本),不包含 <dependencies>(不强制引入依赖)、<modules>(不聚合模块)。

当多模块项目满足以下场景时,BOM 比单纯用父 POM 管理版本更高效:

复制代码
项目拆分为多个独立子系统(如:用户系统、订单系统、支付系统),每个子系统有自己的父 POM,但需要共享第三方依赖版本(如 Spring、MyBatis); 
团队内有多个跨项目复用的依赖(如:公共工具包、中间件客户端),需要统一版本避免冲突;
多模块项目依赖的第三方组件版本较多(如 Spring Boot + MyBatis + Redis + MySQL),需要集中管理,避免  "一处升级、处处修改"。

举个例子:如果没有 BOM,当需要将 spring-core 从 5.3.27 升级到 5.3.30 时,可能需要修改所有子模块的父 POM;而用 BOM 后,只需修改 BOM 中的版本,所有引用 BOM 的模块会自动继承新版本。

2.多模块项目中 BOM 的实战用法

下面以「大型多模块项目」为例,演示 BOM 的「创建→导入→使用」全流程:

项目结构(补充 BOM 模块后)

yaml 复制代码
my-project (总父项目:聚合所有模块,含BOM)
├── pom.xml (总父POM:聚合子模块,可继承基础配置)
├── my-project-bom (BOM模块:纯版本管理)
│   └── pom.xml (BOM的核心配置)
├── module-api (子模块:接口层)
│   └── pom.xml
├── module-service (子模块:服务层)
│   └── pom.xml
└── module-dao (子模块:数据访问层)
    └── pom.xml

步骤 1:创建 BOM 模块(my-project-bom/pom.xml)

BOM 模块仅负责声明依赖版本,不引入任何依赖,也不聚合模块:

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>

    <!-- BOM 模块的 GAV 坐标(必须唯一,供其他模块导入) -->
    <parent>
        <groupId>com.example</groupId>
        <artifactId>my-project</artifactId>
        <version>1.0-SNAPSHOT</version>
        <relativePath>../pom.xml</relativePath>
    </parent>

    <artifactId>my-project-bom</artifactId>
    <packaging>pom</packaging> <!-- BOM 必须是 pom 打包类型 -->
    <name>My Project BOM</name>
    <description>统一管理多模块依赖版本</description>

    <!-- 核心:声明所有依赖的版本(仅声明,不引入) -->
    <dependencyManagement>
        <dependencies>
            <!-- 1. 第三方框架版本 -->
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter</artifactId>
                <version>2.7.10</version>
            </dependency>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-web</artifactId>
                <version>2.7.10</version>
            </dependency>
            <dependency>
                <groupId>org.mybatis.spring.boot</groupId>
                <artifactId>mybatis-spring-boot-starter</artifactId>
                <version>2.3.1</version>
            </dependency>

            <!-- 2. 数据库相关 -->
            <dependency>
                <groupId>mysql</groupId>
                <artifactId>mysql-connector-java</artifactId>
                <version>8.0.32</version>
            </dependency>

            <!-- 3. 内部模块版本(多模块间依赖) -->
            <dependency>
                <groupId>com.example</groupId>
                <artifactId>module-api</artifactId>
                <version>${project.version}</version> <!-- 继承总父项目版本 -->
            </dependency>

            <!-- 4. 测试依赖 -->
            <dependency>
                <groupId>junit</groupId>
                <artifactId>junit</artifactId>
                <version>4.13.2</version>
                <scope>test</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>
</project>

步骤 2:在总父 POM 中聚合 BOM 模块

总父 POM(my-project/pom.xml)需要将 BOM 模块纳入聚合,确保编译时先构建 BOM:

xml 复制代码
<project>
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.example</groupId>
    <artifactId>my-project</artifactId>
    <version>1.0-SNAPSHOT</version>
    <packaging>pom</packaging>
    <name>My Project Parent</name>

    <!-- 聚合所有模块(含 BOM 模块) -->
    <modules>
        <module>my-project-bom</module> <!-- 先聚合 BOM,再聚合业务模块 -->
        <module>module-api</module>
        <module>module-service</module>
        <module>module-dao</module>
    </modules>

    <!-- 父POM可配置通用构建规则(如编译版本),不管理依赖版本(交给BOM) -->
    <build>
        <pluginManagement>
            <plugins>
                <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-compiler-plugin</artifactId>
                    <version>3.8.1</version>
                    <configuration>
                        <source>8</source>
                        <target>8</target>
                    </configuration>
                </plugin>
            </plugins>
        </pluginManagement>
    </build>
</project>

步骤 3:子模块导入 BOM 并使用依赖

所有业务子模块(如 module-service)无需再声明依赖版本,只需通过 导入 BOM,直接使用依赖即可:

子模块 pom.xml(module-service/pom.xml)

xml 复制代码
<?xml version="1.0" encoding="UTF-8"?>
<project>
    <modelVersion>4.0.0</modelVersion>

    <!-- 继承总父POM(获取构建配置) -->
    <parent>
        <groupId>com.example</groupId>
        <artifactId>my-project</artifactId>
        <version>1.0-SNAPSHOT</version>
        <relativePath>../pom.xml</relativePath>
    </parent>

    <artifactId>module-service</artifactId>
    <name>Module Service</name>

    <!-- 核心:导入 BOM,继承所有依赖版本 -->
    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>com.example</groupId>
                <artifactId>my-project-bom</artifactId>
                <version>${project.version}</version>
                <type>pom</type> <!-- 类型为 pom -->
                <scope>import</scope> <!-- 导入 scope,仅用于 BOM -->
            </dependency>
        </dependencies>
    </dependencyManagement>

    <!-- 使用依赖:无需声明 version(BOM 已统一管理) -->
    <dependencies>
        <!-- 内部模块依赖 -->
        <dependency>
            <groupId>com.example</groupId>
            <artifactId>module-api</artifactId>
        </dependency>

        <!-- 第三方依赖 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>

        <!-- 测试依赖 -->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>
</project>

关键说明:import 作用域

子模块导入 BOM 时,必须指定 import 和 pom,这是 Maven 专门为 BOM 设计的导入机制:

复制代码
import 仅作用于 <dependencyManagement>,表示 "将 BOM 中的依赖版本配置导入到当前项目的依赖管理中";
导入后,当前模块的 <dependencies> 中引用 BOM 已声明的依赖时,无需再写 <version>,自动使用 BOM 中的版本; 
一个模块可以导入多个 BOM(如:项目自定义 BOM + Spring Boot 官方 BOM),优先级以 "后导入的 BOM" 为准。

3.BOM vs 父 POM:多模块项目该怎么选?

特性 父 POM(Parent POM) BOM(Bill of Materials)
核心作用 模块聚合 + 依赖继承 + 构建配置(编译、插件) 纯依赖版本管理(仅声明版本,不强制引入)
使用方式 子模块通过 标签继承 子模块通过 + import 导入
依赖引入 可通过 强制子模块继承依赖 不引入依赖,仅提供版本,子模块按需引入
灵活性 强耦合(子模块必须继承父 POM) 松耦合(可导入多个 BOM,不影响其他配置)
适用场景 单一项目的多模块聚合、统一构建规则 多项目共享依赖版本、大型多模块项目版本统一

最佳实践:

复制代码
小型多模块项目(10 个以内模块):直接用「父 POM + <dependencyManagement>」管理版本,简单高效;
中大型多模块项目 / 跨项目协作:用「父 POM(管聚合 + 构建)+ BOM(管版本)」,兼顾灵活性和统一性; 
引用第三方框架(如 Spring Boot):直接导入官方 BOM(如 spring-boot-dependencies),避免手动声明版本。

4.进阶:导入第三方官方 BOM(如 Spring Boot)

在多模块项目中,我们通常会直接导入 Spring Boot 官方 BOM,无需手动声明 Spring 相关依赖的版本。示例如下:

子模块中导入 Spring Boot BOM + 自定义 BOM

xml 复制代码
<dependencyManagement>
    <dependencies>
        <!-- 1. 导入 Spring Boot 官方 BOM(优先级低) -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-dependencies</artifactId>
            <version>2.7.10</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>

        <!-- 2. 导入自定义 BOM(优先级高,可覆盖官方版本) -->
        <dependency>
            <groupId>com.example</groupId>
            <artifactId>my-project-bom</artifactId>
            <version>${project.version}</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>
复制代码
优先级规则:后导入的 BOM 会覆盖先导入的 BOM 中相同依赖的版本; 
好处:直接复用 Spring Boot 官方的版本兼容性配置,避免手动匹配版本(如 Spring 与 Spring Boot 的版本兼容)。

六、总结

Maven 不仅是"依赖管理工具",更是Java项目的"标准化骨架"。它通过POM文件统一配置、仓库统一存储依赖、生命周期统一构建流程,极大提升了项目的可维护性和团队协作效率。

POM 和 BOM 是 Maven 中核心的配置载体,二者互补协作,前者管 "项目全量配置",后者专管 "依赖版本统一",核心定位与差异如下:

1.POM(Project Object Model)

复制代码
1.本质:每个 Maven 项目的 "标配核心配置文件"(pom.xml),是项目的 "说明书 + 操作入口"。 
2.核心作用:
定义项目标识(GAV 坐标)、依赖引入(<dependencies>)、构建规则(插件、编译版本等);
支持多模块聚合(<modules>)与配置继承(<parent>); 
Maven 执行所有命令(如 compile、package)的核心依据。

2.BOM(Bill of Materials)

复制代码
1.本质:特殊的 POM 文件(仅打包类型为 pom),是 "纯依赖版本清单"。 
2.核心作用: 
集中声明依赖版本(仅通过 <dependencyManagement> 声明,不主动引入依赖); 
解决多模块 / 跨项目的版本冲突,实现 "一处配置,处处复用";
不涉及模块聚合、构建规则等其他配置,专注版本统一。

简单来说就是:

复制代码
小项目 / 单一多模块项目:用 POM 即可覆盖 "配置 + 版本管理",简单高效; 
中大型多模块 / 跨项目:用 POM 管 "构建 + 聚合",用 BOM 管 "版本统一",互补更灵活; 
BOM 是 POM 的 "专项增强",仅聚焦版本问题,不替代 POM 的核心功能。
相关推荐
搬山境KL攻城狮17 小时前
maven 私服上传jar
java·maven·jar
一只小灿灿2 天前
深入解析 Maven 与 Gradle:Java 项目构建工具的安装、使用
java·开发语言·maven
深色風信子2 天前
Java Maven Log4j 项目日志打印
java·log4j·maven·java maven
CodeAmaz2 天前
统一发包管理(Maven 仓库)详细步骤
java·maven·运维开发·个人开发
小马爱打代码2 天前
Maven:详细学习笔记
maven
多多*3 天前
maven常用的命令
java·log4j·maven
水月wwww3 天前
Maven项目及Tomcat配置(IDEA)
tomcat·maven·intellij-idea·javaweb
高斯林.神犇3 天前
maven专题
maven
.格子衫.3 天前
Maven的下载与安装
java·maven