🏗️ 35 Maven项目管理——POM详解、依赖管理与多模块实战

更新日期:2026年5月 | Java入门到精通系列 · 第五阶段·企业级开发
© 版权声明:本文为原创技术文章,转载请联系作者并注明出处。



一、Maven概述

1.1 什么是Maven

Maven 是 Apache 开源的项目管理与构建工具,基于 POM(Project Object Model)概念,能够自动化管理项目的构建、报告和文档。

1.2 Maven核心功能

功能 说明
依赖管理 自动下载、管理第三方jar包
项目构建 编译、测试、打包、部署一键完成
统一目录结构 约定优于配置,统一项目结构
模块化管理 支持多模块拆分与聚合
插件扩展 丰富的插件生态

1.3 Maven安装与配置

# 1. 下载Maven(以3.9.x为例)
# https://maven.apache.org/download.cgi

# 2. 解压并配置环境变量
export MAVEN_HOME=/usr/local/apache-maven-3.9.6
export PATH=$MAVEN_HOME/bin:$PATH

# 3. 验证安装
mvn -version

# 4. 配置国内镜像(settings.xml)

settings.xml 配置阿里云镜像:

<!-- ~/.m2/settings.xml -->
<settings>
    <mirrors>
        <mirror>
            <id>aliyun</id>
            <name>Aliyun Maven Mirror</name>
            <url>https://maven.aliyun.com/repository/public</url>
            <mirrorOf>central</mirrorOf>
        </mirror>
    </mirrors>
    
    <localRepository>/Users/yourname/.m2/repository</localRepository>
</settings>

二、POM文件详解

2.1 POM基本结构

<?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">
    
    <!-- POM模型版本,固定值 -->
    <modelVersion>4.0.0</modelVersion>
    
    <!-- 项目坐标 -->
    <groupId>com.example</groupId>        <!-- 组织标识 -->
    <artifactId>my-project</artifactId>   <!-- 项目名称 -->
    <version>1.0.0</version>              <!-- 版本号 -->
    <packaging>jar</packaging>            <!-- 打包方式 -->
    
    <!-- 项目信息 -->
    <name>My Project</name>
    <description>A sample Maven project</description>
    
    <!-- 属性定义 -->
    <properties>
        <java.version>21</java.version>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>
    
    <!-- 依赖管理 -->
    <dependencies>
        <!-- 具体依赖 -->
    </dependencies>
    
    <!-- 构建配置 -->
    <build>
        <!-- 插件配置 -->
    </build>
</project>

2.2 GAV坐标详解

Maven 通过 GAV(GroupId + ArtifactId + Version) 三个维度唯一标识一个构件:

属性 说明 命名规范 示例
groupId 组织/公司标识 反转域名 com.example
artifactId 项目/模块名 小写中划线 user-service
version 版本号 语义版本 1.0.0-SNAPSHOT
packaging 打包类型 jar/war/pom jar

2.3 版本号规范

主版本号.次版本号.增量版本号-里程碑版本

示例:
1.0.0         -> 正式发布版本
1.0.0-SNAPSHOT -> 快照版本(开发中)
1.0.0-RELEASE  -> 发布版
1.0.0-beta.1   -> Beta测试版

2.4 packaging类型

类型 说明 适用场景
jar Java归档包(默认) 普通Java项目、工具库
war Web应用归档包 传统Web项目
pom 父POM,不含代码 多模块父工程
maven-plugin Maven插件 自定义插件

三、依赖管理

3.1 依赖配置

<dependencies>
    <!-- 基本依赖 -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
        <version>3.3.5</version>
    </dependency>
    
    <!-- 带作用域的依赖 -->
    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>4.13.2</version>
        <scope>test</scope>
    </dependency>
    
    <!-- 可选依赖 -->
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <version>8.0.33</version>
        <optional>true</optional>
    </dependency>
</dependencies>

3.2 依赖作用域(scope)

Scope 编译 测试 运行 传递 典型例子
compile spring-core(默认)
provided servlet-api、lombok
runtime mysql-connector
test junit、mockito
system 本地jar(不推荐)

3.3 依赖传递

A -> B -> C(C是B的compile依赖)
则A自动引入C

A -> B -> D(D是B的test/provided依赖)
则A不会引入D

3.4 依赖排除

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-redis</artifactId>
    <!-- 排除不需要的传递依赖 -->
    <exclusions>
        <exclusion>
            <groupId>io.lettuce</groupId>
            <artifactId>lettuce-core</artifactId>
        </exclusion>
    </exclusions>
</dependency>

3.5 dependencyManagement

父POM中统一管理依赖版本,子模块只需声明 groupId 和 artifactId,无需指定 version:

<!-- 父POM -->
<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-databind</artifactId>
            <version>2.17.0</version>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.34</version>
        </dependency>
    </dependencies>
</dependencyManagement>
<!-- 子模块POM(无需写version) -->
<dependencies>
    <dependency>
        <groupId>com.fasterxml.jackson.core</groupId>
        <artifactId>jackson-databind</artifactId>
    </dependency>
    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
    </dependency>
</dependencies>

3.6 BOM(Bill of Materials)

Spring Boot 提供了官方BOM,可以统一管理所有Spring生态依赖版本:

<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-dependencies</artifactId>
            <version>3.3.5</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>

3.7 依赖冲突解决

策略 说明
最短路径优先 依赖链更短的版本优先
先声明优先 相同路径长度,POM中先声明的优先
exclusions 手动排除不需要的版本
依赖仲裁 mvn dependency:tree 查看依赖树
# 查看依赖树
mvn dependency:tree

# 分析依赖冲突
mvn dependency:analyze

四、多模块项目

4.1 项目结构

my-platform/
├── pom.xml                    <!-- 父POM(packaging=pom) -->
├── my-platform-common/        <!-- 公共模块 -->
│   ├── pom.xml
│   └── src/
├── my-platform-service/       <!-- 业务服务模块 -->
│   ├── pom.xml
│   └── src/
├── my-platform-web/           <!-- Web接口模块 -->
│   ├── pom.xml
│   └── src/
└── my-platform-app/           <!-- 启动模块 -->
    ├── pom.xml
    └── src/

4.2 父POM配置

<?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.example</groupId>
    <artifactId>my-platform</artifactId>
    <version>1.0.0</version>
    <packaging>pom</packaging>
    
    <!-- 聚合子模块 -->
    <modules>
        <module>my-platform-common</module>
        <module>my-platform-service</module>
        <module>my-platform-web</module>
        <module>my-platform-app</module>
    </modules>
    
    <properties>
        <java.version>21</java.version>
        <spring-boot.version>3.3.5</spring-boot.version>
        <mybatis-plus.version>3.5.7</mybatis-plus.version>
    </properties>
    
    <!-- 版本统一管理 -->
    <dependencyManagement>
        <dependencies>
            <!-- Spring Boot BOM -->
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-dependencies</artifactId>
                <version>${spring-boot.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
            
            <!-- 内部模块 -->
            <dependency>
                <groupId>com.example</groupId>
                <artifactId>my-platform-common</artifactId>
                <version>${project.version}</version>
            </dependency>
            <dependency>
                <groupId>com.example</groupId>
                <artifactId>my-platform-service</artifactId>
                <version>${project.version}</version>
            </dependency>
            <dependency>
                <groupId>com.example</groupId>
                <artifactId>my-platform-web</artifactId>
                <version>${project.version}</version>
            </dependency>
        </dependencies>
    </dependencyManagement>
    
    <!-- 全局构建配置 -->
    <build>
        <pluginManagement>
            <plugins>
                <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-compiler-plugin</artifactId>
                    <version>3.13.0</version>
                    <configuration>
                        <source>${java.version}</source>
                        <target>${java.version}</target>
                        <encoding>UTF-8</encoding>
                    </configuration>
                </plugin>
            </plugins>
        </pluginManagement>
    </build>
</project>

4.3 子模块POM

common模块(基础工具):

<project>
    <parent>
        <groupId>com.example</groupId>
        <artifactId>my-platform</artifactId>
        <version>1.0.0</version>
    </parent>
    
    <artifactId>my-platform-common</artifactId>
    <packaging>jar</packaging>
    
    <dependencies>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>
        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-databind</artifactId>
        </dependency>
    </dependencies>
</project>

service模块(依赖common):

<project>
    <parent>
        <groupId>com.example</groupId>
        <artifactId>my-platform</artifactId>
        <version>1.0.0</version>
    </parent>
    
    <artifactId>my-platform-service</artifactId>
    
    <dependencies>
        <!-- 依赖内部common模块 -->
        <dependency>
            <groupId>com.example</groupId>
            <artifactId>my-platform-common</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>
    </dependencies>
</project>

app模块(启动模块):

<project>
    <parent>
        <groupId>com.example</groupId>
        <artifactId>my-platform</artifactId>
        <version>1.0.0</version>
    </parent>
    
    <artifactId>my-platform-app</artifactId>
    
    <dependencies>
        <dependency>
            <groupId>com.example</groupId>
            <artifactId>my-platform-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
    </dependencies>
    
    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
</project>

4.4 模块依赖关系

my-platform-app
    └── my-platform-web
            └── my-platform-service
                    └── my-platform-common

五、私服搭建与配置

5.1 什么是Maven私服

私服是一种特殊的Maven仓库,架设在局域网内,代理外部仓库并缓存构件,同时托管内部项目的构件。

5.2 Nexus安装

# 使用Docker快速搭建Nexus3
docker run -d \
    --name nexus3 \
    -p 8081:8081 \
    -v nexus-data:/nexus-data \
    sonatype/nexus3:latest

# 访问管理界面
# http://localhost:8081
# 默认管理员密码在 /nexus-data/admin.password 文件中

5.3 仓库类型

类型 说明 用途
hosted 宿主仓库 存放内部项目的构件
proxy 代理仓库 代理远程公共仓库
group 仓库组 聚合多个仓库,对外统一访问

5.4 settings.xml配置私服

<settings>
    <!-- 服务认证信息 -->
    <servers>
        <server>
            <id>nexus-releases</id>
            <username>admin</username>
            <password>admin123</password>
        </server>
        <server>
            <id>nexus-snapshots</id>
            <username>admin</username>
            <password>admin123</password>
        </server>
    </servers>
    
    <!-- 镜像配置 -->
    <mirrors>
        <mirror>
            <id>nexus</id>
            <mirrorOf>*</mirrorOf>
            <name>Nexus Mirror</name>
            <url>http://localhost:8081/repository/maven-public/</url>
        </mirror>
    </mirrors>
    
    <!-- Profile配置 -->
    <profiles>
        <profile>
            <id>nexus</id>
            <repositories>
                <repository>
                    <id>central</id>
                    <url>http://localhost:8081/repository/maven-public/</url>
                    <releases><enabled>true</enabled></releases>
                    <snapshots><enabled>true</enabled></snapshots>
                </repository>
            </repositories>
            <pluginRepositories>
                <pluginRepository>
                    <id>central</id>
                    <url>http://localhost:8081/repository/maven-public/</url>
                </pluginRepository>
            </pluginRepositories>
        </profile>
    </profiles>
    
    <activeProfiles>
        <activeProfile>nexus</activeProfile>
    </activeProfiles>
</settings>

5.5 发布到私服

在项目POM中配置发布地址:

<distributionManagement>
    <repository>
        <id>nexus-releases</id>
        <name>Nexus Release Repository</name>
        <url>http://localhost:8081/repository/maven-releases/</url>
    </repository>
    <snapshotRepository>
        <id>nexus-snapshots</id>
        <name>Nexus Snapshot Repository</name>
        <url>http://localhost:8081/repository/maven-snapshots/</url>
    </snapshotRepository>
</distributionManagement>
# 发布到私服
mvn deploy

六、常用插件详解

6.1 编译插件

<build>
    <plugins>
        <!-- 编译插件 -->
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-compiler-plugin</artifactId>
            <version>3.13.0</version>
            <configuration>
                <source>21</source>
                <target>21</target>
                <encoding>UTF-8</encoding>
                <compilerArgs>
                    <arg>-parameters</arg>
                </compilerArgs>
            </configuration>
        </plugin>
    </plugins>
</build>

6.2 Spring Boot插件

<plugin>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-maven-plugin</artifactId>
    <version>3.3.5</version>
    <executions>
        <execution>
            <goals>
                <goal>repackage</goal>
            </goals>
        </execution>
    </executions>
</plugin>
# 打包可执行jar
mvn clean package

# 运行
java -jar target/my-app-1.0.0.jar

6.3 测试插件

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-surefire-plugin</artifactId>
    <version>3.2.5</version>
    <configuration>
        <!-- 跳过测试 -->
        <skipTests>false</skipTests>
        <!-- 包含的测试 -->
        <includes>
            <include>**/*Test.java</include>
        </includes>
    </configuration>
</plugin>

6.4 代码检查插件

<!-- SpotBugs静态分析 -->
<plugin>
    <groupId>com.github.spotbugs</groupId>
    <artifactId>spotbugs-maven-plugin</artifactId>
    <version>4.8.3.1</version>
</plugin>

<!-- Checkstyle代码规范 -->
<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-checkstyle-plugin</artifactId>
    <version>3.3.1</version>
</plugin>

6.5 常用插件汇总

插件 功能 命令
maven-compiler-plugin 编译Java代码 mvn compile
maven-surefire-plugin 运行单元测试 mvn test
maven-jar-plugin 打jar包 mvn package
maven-source-plugin 生成源码包 mvn source:jar
maven-javadoc-plugin 生成JavaDoc mvn javadoc:javadoc
maven-clean-plugin 清理构建产物 mvn clean
maven-install-plugin 安装到本地仓库 mvn install
maven-deploy-plugin 发布到远程仓库 mvn deploy
versions-maven-plugin 版本管理 mvn versions:display-dependency-updates

七、Maven常用命令

7.1 生命周期

Maven有三套独立的生命周期:

生命周期 阶段(按顺序执行)
clean pre-clean → clean → post-clean
default validate → compile → test → package → verify → install → deploy
site pre-site → site → post-site → site-deploy

7.2 常用命令

# 清理并打包(跳过测试)
mvn clean package -DskipTests

# 安装到本地仓库
mvn clean install

# 发布到远程仓库
mvn clean deploy

# 仅编译
mvn compile

# 运行测试
mvn test

# 运行指定测试
mvn -Dtest=UserServiceTest test

# 查看依赖树
mvn dependency:tree

# 分析未使用的依赖
mvn dependency:analyze

# 更新SNAPSHOT依赖
mvn clean install -U

# 离线模式(不从远程下载)
mvn clean package -o

# 生成项目骨架
mvn archetype:generate

# 运行Spring Boot应用
mvn spring-boot:run

# 查看有效POM(合并继承后的完整POM)
mvn help:effective-pom

7.3 常用属性

# 跳过测试
mvn package -DskipTests        # 跳过测试执行
mvn package -Dmaven.test.skip=true  # 跳过测试编译和执行

# 指定Profile
mvn package -P prod

# 指定环境变量
mvn spring-boot:run -Dspring-boot.run.profiles=dev

八、常见面试题解析

Q1:Maven的依赖传递规则是什么?

Maven的依赖传递遵循以下规则:

  1. compile 范围的依赖会传递到所有依赖该项目的模块
  2. testprovided 范围的依赖不会传递
  3. 当传递依赖出现版本冲突时,采用最短路径优先先声明优先策略

Q2:dependencyManagement 和 dependencies 的区别?

特性 dependencies dependencyManagement
版本声明 必须指定version 可以不指定version
子模块继承 自动继承所有依赖 只继承版本,需子模块显式声明
用途 直接引入依赖 统一版本管理

Q3:SNAPSHOT和RELEASE版本的区别?

特性 SNAPSHOT RELEASE
稳定性 不稳定,开发中 稳定发布版
更新策略 每次构建自动检查更新 下载后缓存,不自动更新
部署限制 可重复部署 通常不可重复部署
版本号格式 x.x.x-SNAPSHOT x.x.x

Q4:如何解决Maven依赖冲突?

# 1. 查看依赖树,找到冲突
mvn dependency:tree -Dverbose -Dincludes=com.google.guava:guava

# 2. 使用exclusions排除冲突版本
<dependency>
    <groupId>com.example</groupId>
    <artifactId>some-lib</artifactId>
    <exclusions>
        <exclusion>
            <groupId>com.google.guava</groupId>
            <artifactId>guava</artifactId>
        </exclusion>
    </exclusions>
</dependency>

# 3. 在dependencyManagement中锁定版本
<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>com.google.guava</groupId>
            <artifactId>guava</artifactId>
            <version>33.0.0-jre</version>
        </dependency>
    </dependencies>
</dependencyManagement>

九、总结与下篇预告

本篇要点回顾

主题 核心内容
POM详解 GAV坐标、packaging、properties、build
依赖管理 scope、传递、排除、dependencyManagement、BOM
多模块 父子POM、模块聚合、层次依赖
私服 Nexus搭建、仓库类型、发布配置
常用插件 compiler、surefire、spring-boot、javadoc

💬 互动问题

  1. 你在项目中是如何管理多模块依赖的?
  2. 遇到过哪些棘手的依赖冲突问题,如何解决的?
  3. 你们公司使用什么私服方案?

📢 下篇预告

下一篇:【36 数据库编程】——我们将学习JDBC编程、连接池(HikariCP)、事务管理、SQL注入防护等数据库操作核心技术,为后续的ORM框架打好基础!


参考资料

Logo

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。

更多推荐