Maven 是 Java 生态中最主流的项目管理与自动化构建工具 ,由Apache基金会维护。它的核心价值在于解决传统Java项目的两大痛点:手动管理 Jar 包的混乱和构建流程的不统一,通过标准化的配置和命令,让开发者专注于代码逻辑而非项目运维。
目录
- [一、Maven 核心概念](#一、Maven 核心概念)
- 二、Maven环境搭建
-
- 1.前置条件
- [2.下载安装 Maven](#2.下载安装 Maven)
- 3.配置本地仓库与镜像
- [三、Maven 实战:常用操作与命令](#三、Maven 实战:常用操作与命令)
-
- [1. 创建 Maven 项目](#1. 创建 Maven 项目)
- 2.核心构建命令
- 3.解决依赖冲突(实战场景)
- [四、Maven 进阶:多模块项目](#四、Maven 进阶:多模块项目)
-
- 1.多模块项目结构
- [2.父项目 POM 配置(parent-project/pom.xml)](#2.父项目 POM 配置(parent-project/pom.xml))
- [3.子模块 POM 配置(module-service/pom.xml)](#3.子模块 POM 配置(module-service/pom.xml))
- [五、BOM 的定义和使用](#五、BOM 的定义和使用)
-
- 1.BOM的核心定位和核心价值
- [2.多模块项目中 BOM 的实战用法](#2.多模块项目中 BOM 的实战用法)
- [3.BOM vs 父 POM:多模块项目该怎么选?](#3.BOM vs 父 POM:多模块项目该怎么选?)
- [4.进阶:导入第三方官方 BOM(如 Spring Boot)](#4.进阶:导入第三方官方 BOM(如 Spring Boot))
- 六、总结
-
- [1.POM(Project Object Model)](#1.POM(Project Object Model))
- [2.BOM(Bill of Materials)](#2.BOM(Bill of Materials))
一、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 的核心功能。