Featured image of post Maven 全套实战:从安装到多模块企业级构建

Maven 全套实战:从安装到多模块企业级构建

Maven 3.9 + settings.xml + 多模块项目 + 阿里云镜像 + profile 多环境完整路径

Maven 全套实战:从安装到多模块企业级构建

背景与价值

Maven 是 Java 生态事实标准构建工具(Ant 已老、Gradle 学习成本高)。核心价值:

  • 依赖管理:自动下载 jar 及其传递依赖,避免版本冲突
  • 标准化结构src/main/javasrc/test/java 等约定优于配置
  • 多模块管理:父子 POM 继承 + dependencyManagement 统一版本
  • 构建生命周期compile / test / package / install / deploy 一键式

本文按"安装 → 核心配置 → 多模块 → 实战坑"完整路径展开,基于 Maven 3.9.x 实测。

安装与配置

1. 下载解压

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
# Linux
curl -O https://archive.apache.org/dist/maven/maven-3/3.9.6/binaries/apache-maven-3.9.6-bin.tar.gz
mkdir -p /opt/maven
tar -zxvf apache-maven-3.9.6-bin.tar.gz -C /opt/maven

# 配置环境变量
export JAVA_HOME=/opt/java/jdk1.8.0_381
export MAVEN_HOME=/opt/maven
export PATH=.:$JAVA_HOME/bin:$JAVA_HOME/jre/bin:$MAVEN_HOME/bin:$PATH

# 验证
mvn -version
# Apache Maven 3.9.6 (8c8575b0e1b8...)
# Java version: 1.8.0_381

2. 全局配置文件 ${maven_home}/conf/settings.xml

settings.xml 集中管理仓库镜像、代理、profile、服务器认证等全局配置,避免每个项目单独配。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
<?xml version="1.0" encoding="UTF-8"?>
<settings xmlns="http://maven.apache.org/SETTINGS/1.2.0">

    <!-- 本地仓库路径(默认 ${user.home}/.m2/repository) -->
    <!--<localRepository>/path/to/local/repo</localRepository>-->

    <!-- 离线模式(无法联网时) -->
    <!--<offline>false</offline>-->

    <!-- 代理(公司内网访问外网 Maven 中央仓库时) -->
    <proxies>
        <proxy>
            <id>myproxy</id>
            <active>true</active>
            <protocol>http</protocol>
            <host>proxy.example.com</host>
            <port>8080</port>
            <username>proxyuser</username>
            <password>{{PROXY_PASSWORD}}</password>
            <nonProxyHosts>*.google.com|ibiblio.org</nonProxyHosts>
        </proxy>
    </proxies>

    <!-- 服务器认证(部署到 Nexus / 私库时用) -->
    <servers>
        <server>
            <id>nexus-releases</id>
            <username>{{NEXUS_USER}}</username>
            <password>{{NEXUS_PASSWORD}}</password>
        </server>
    </servers>

    <!-- 镜像(关键:阿里云加速国内下载) -->
    <mirrors>
        <mirror>
            <id>aliyun-public</id>
            <name>阿里云 Maven 公共仓库</name>
            <url>https://maven.aliyun.com/repository/public</url>
            <mirrorOf>central</mirrorOf>
        </mirror>
    </mirrors>

    <!-- 多环境 Profile -->
    <profiles>
        <profile>
            <id>jdk-1.8</id>
            <activation>
                <activeByDefault>true</activeByDefault>
            </activation>
            <properties>
                <maven.compiler.source>1.8</maven.compiler.source>
                <maven.compiler.target>1.8</maven.compiler.target>
            </properties>
        </profile>
    </profiles>
</settings>

3. 阿里云镜像配置(关键)

国内访问 Maven 中央仓库(repo1.maven.org)经常超时,建议配置阿里云镜像:

仓库类型阿里云地址
公共仓库https://maven.aliyun.com/repository/public
Googlehttps://maven.aliyun.com/repository/google
Springhttps://maven.aliyun.com/repository/spring
Apache Snapshotshttps://maven.aliyun.com/repository/apache-snapshots

配置示例(settings.xml 镜像):

1
2
3
4
5
6
<mirror>
    <id>aliyun-spring</id>
    <name>阿里云 Spring 仓库</name>
    <url>https://maven.aliyun.com/repository/spring</url>
    <mirrorOf>spring-milestones,spring-snapshots</mirrorOf>
</mirror>

核心概念

1. 坐标(GAV)

每个 Maven 构件由三要素唯一定位:

1
2
3
4
5
<dependency>
    <groupId>org.springframework.boot</groupId>   <!-- 组织 -->
    <artifactId>spring-boot-starter-web</artifactId>  <!-- 项目 -->
    <version>3.2.0</version>                      <!-- 版本 -->
</dependency>

2. 仓库类型

类型位置用途
本地仓库~/.m2/repository/已下载的依赖
中央仓库repo1.maven.orgMaven 官方仓库(默认)
私服Nexus / Artifactory公司内网,缓存 + 部署
镜像仓库阿里云 / 华为云中央仓库的国内镜像

3. 依赖范围(Scope)

Scope编译测试运行时例子
compile(默认)spring-core
providedservlet-api(容器提供)
runtimeJDBC 驱动
testJUnit
system引用本地 jar(不推荐)

4. 生命周期阶段

1
2
3
4
5
6
mvn clean          # 清理 target/
mvn compile        # 编译 main
mvn test           # 编译并运行测试
mvn package        # 打包成 jar/war
mvn install        # 安装到本地仓库(供其他模块引用)
mvn deploy         # 部署到远程私服

多模块项目(企业级核心)

1. 父 POM 约定

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
my-project/                    # 父项目根目录
├── pom.xml                    # 父 POM(packaging=pom)
├── my-app/                    # 主应用模块
│   ├── pom.xml
│   └── src/
├── my-common/                 # 公共工具模块
│   ├── pom.xml
│   └── src/
└── my-api/                    # API 定义模块
    ├── pom.xml
    └── src/

2. 父 POM 完整模板

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0">
    <modelVersion>4.0.0</modelVersion>

    <!-- 继承 Spring Boot Starter Parent(统一版本管理) -->
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.6.14</version>
        <relativePath/>
    </parent>

    <groupId>com.example</groupId>
    <artifactId>my-project</artifactId>
    <version>1.0.0-SNAPSHOT</version>
    <packaging>pom</packaging>
    <name>my-project</name>

    <!-- 子模块清单 -->
    <modules>
        <module>my-common</module>
        <module>my-api</module>
        <module>my-app</module>
    </modules>

    <!-- 统一版本管理(子模块引用时不需要写版本号) -->
    <dependencyManagement>
        <dependencies>
            <!-- Spring Cloud -->
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>${spring-cloud.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
            <!-- Spring Cloud Alibaba -->
            <dependency>
                <groupId>com.alibaba.cloud</groupId>
                <artifactId>spring-cloud-alibaba-dependencies</artifactId>
                <version>${spring-cloud-alibaba.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
            <!-- 项目内部模块 -->
            <dependency>
                <groupId>com.example</groupId>
                <artifactId>my-common</artifactId>
                <version>${project.version}</version>
            </dependency>
        </dependencies>
    </dependencyManagement>

    <!-- 公共依赖(所有子模块都会继承) -->
    <dependencies>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <scope>provided</scope>
        </dependency>
    </dependencies>

    <!-- 统一属性 -->
    <properties>
        <java.version>1.8</java.version>
        <maven.compiler.source>${java.version}</maven.compiler.source>
        <maven.compiler.target>${java.version}</maven.compiler.target>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <spring-cloud.version>2021.0.1</spring-cloud.version>
        <spring-cloud-alibaba.version>2021.0.1.0</spring-cloud-alibaba.version>
    </properties>

    <!-- 多环境 Profile -->
    <profiles>
        <profile>
            <id>dev</id>
            <activation>
                <activeByDefault>true</activeByDefault>
            </activation>
            <properties>
                <profile.name>dev</profile.name>
            </properties>
        </profile>
        <profile>
            <id>test</id>
            <properties>
                <profile.name>test</profile.name>
            </properties>
        </profile>
        <profile>
            <id>prod</id>
            <properties>
                <profile.name>prod</profile.name>
            </properties>
        </profile>
    </profiles>
</project>

3. 子模块 POM

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<?xml version="1.0" encoding="UTF-8"?>
<project>
    <parent>
        <groupId>com.example</groupId>
        <artifactId>my-project</artifactId>
        <version>1.0.0-SNAPSHOT</version>
    </parent>

    <artifactId>my-app</artifactId>
    <packaging>jar</packaging>

    <!-- 不需要写版本号(父 dependencyManagement 已管理) -->
    <dependencies>
        <dependency>
            <groupId>com.example</groupId>
            <artifactId>my-common</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
    </dependencies>
</project>

常用命令

命令作用
mvn clean清理 target 目录
mvn compile编译主代码
mvn test运行单元测试
mvn package -DskipTests打包跳过测试
mvn dependency:tree树形展示依赖
mvn dependency:tree -Dincludes=commons-logging过滤特定依赖
mvn help:effective-pom查看完整 POM(合并父子)
mvn -Pprod clean package激活 prod profile 打包
mvn -pl my-app -am package只构建 my-app 及其依赖模块

实战坑

1. 依赖冲突(NoClassDefFoundError / NoSuchMethodError

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
# 查看依赖树
mvn dependency:tree -Dverbose

# 排除传递依赖
<dependency>
    <groupId>com.example</groupId>
    <artifactId>my-lib</artifactId>
    <exclusions>
        <exclusion>
            <groupId>commons-logging</groupId>
            <artifactId>commons-logging</artifactId>
        </exclusion>
    </exclusions>
</dependency>

2. JAR 包冲突定位

1
2
3
4
5
6
# 找哪个 jar 引入的
mvn dependency:tree -Dincludes=com.google.guava:guava

# 输出:
# [INFO] +- com.example:my-lib:jar:1.0:compile
# [INFO] |  \- com.google.guava:guava:jar:30.0-jre:compile  ← 这里

3. SNAPSHOT 版本不稳定

1.0.0-SNAPSHOT 表示"开发中快照",Maven 默认每次构建都拉取最新。生产环境应锁定 release 版本。

4. mvn package 跳过测试

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
# 方式 1:命令行参数
mvn package -DskipTests

# 方式 2:surefire 插件配置
<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-surefire-plugin</artifactId>
    <configuration>
        <skipTests>true</skipTests>
    </configuration>
</plugin>

5. 配置中心化 vs 分散

  • 统一管理:父 POM dependencyManagement 集中版本
  • 覆盖:子模块可显式覆盖(极少数情况)
  • 避免:每个子模块独立写版本号(升级时全项目都要改)

Maven Wrapper(推荐)

mvnw 是项目自带的 Maven 包装脚本,避免开发者本地 Maven 版本不一致

1
2
3
4
5
6
7
8
9
# 生成 wrapper(项目根目录执行一次)
mvn -N io.takari:maven:0.7.7:wrapper -Dmaven=3.9.6

# 提交到 Git
git add mvnw mvnw.cmd .mvn/
git commit -m "build: 添加 Maven Wrapper"

# 团队成员执行(无需安装 Maven)
./mvnw clean package

私服搭建(Nexus 3.x)

1
2
3
4
5
6
# Docker 一键启动
docker run -d \
  -p 8081:8081 \
  -v /data/nexus-data:/nexus-data \
  --name nexus \
  sonatype/nexus3:3.64.0

部署到 Nexus:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
<!-- 项目 pom.xml -->
<distributionManagement>
    <repository>
        <id>nexus-releases</id>     <!-- 对应 settings.xml server id -->
        <url>http://{{NEXUS_HOST}}:8081/repository/maven-releases/</url>
    </repository>
    <snapshotRepository>
        <id>nexus-snapshots</id>
        <url>http://{{NEXUS_HOST}}:8081/repository/maven-snapshots/</url>
    </snapshotRepository>
</distributionManagement>

<build>
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-deploy-plugin</artifactId>
        </plugin>
    </plugins>
</build>
1
mvn deploy   # 部署到 Nexus

前置知识与下一步

前置

  • Java 基础语法、IDE 使用
  • 基本的命令行操作
  • 了解 Spring Boot 项目结构

下一步

  • 复杂构建用 Maven Profile + Resource Filtering 实现多环境打包
  • 配合 Dockerfile + CI/CD 一键出镜像
  • 巨型项目切分用 Maven 多仓库 + 微服务,避免单仓库超大

小结

Maven 3.9 + 阿里云镜像 + 标准 settings.xml 是企业 Java 项目的"开箱即用"组合。多模块项目靠父 POM dependencyManagement 统一版本 + 子 POM 引用简化,是避免"依赖版本地狱"的关键。Maven Wrapper 解决了团队成员本地 Maven 版本不一致的痛点。Nexus 私服是企业内网依赖缓存 + 内部 jar 部署的标配。


2024+ 视角:Maven 4 预览 + Gradle 8 对比

Maven 4.0 关键变化(2024 仍在预发布)

  • POM 结构化:XML → 仍是 XML,但解析器重写(Lexical 三遍解析),速度 +30%
  • 多语言项目支持:原 Maven 只管 Java,Maven 4 开始支持 JS / Python / Rust 子项目
  • dependencyManagement 路径表达式:支持 ${groupId:artifactId:type:version} 直接引用父项目
  • CI 集成深度增强mvn verify 输出 SBOM(软件物料清单)——合规审计直接用
  • MVN Daemon(实验):常驻进程 + 增量编译,类似 Gradle Daemon

Maven 4 升级路径

1
2
3
4
5
6
7
8
<!-- 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>
    ...
</project>

主要差异:

  • POM modelVersion 不变(仍是 4.0.0)
  • 升级命令:mvn -P maven-4-upgrade verify(Maven 4 自带)
  • 大部分插件需升级到 4.x 版本

Gradle 8.x 与 Maven 4 的 2024+ 对比

维度Maven 4Gradle 8.x
构建速度较慢(提升 30%)快 2-10 倍(增量 + 守护进程)
配置语言XMLKotlin DSL / Groovy
增量构建需 mvn incremental原生支持
多语言实验Kotlin Multiplatform / Android
生态稳定性25 年沉淀,文档全较新,插件质量参差
学习曲线低(约定优于配置)中(DSL 学习)
企业 Java 占比70%+15%

选型建议

  • 新项目(Kotlin / Android / 复杂构建):Gradle 8.x
  • 传统 Spring / 金融 / 政府Maven 仍是首选——团队上手快、CI 配置简单
  • Kotlin Multiplatform / 跨平台必须 Gradle

镜像配置的 2024+ 演进

阿里云 2023 年起对 Maven 中央仓库做了全量同步,但 2024 之后新增了:

  • 华为云镜像https://repo.huaweicloud.com/repository/maven/
  • 腾讯云镜像https://mirrors.cloud.tencent.com/nexus/repository/maven-public/
  • 中国移动云镜像https://mirrors.cmecloud.cn/repository/maven/
1
2
3
4
5
6
7
<mirrors>
    <mirror>
        <id>huawei-cloud</id>
        <url>https://repo.huaweicloud.com/repository/maven/</url>
        <mirrorOf>central</mirrorOf>
    </mirror>
</mirrors>

dependencyManagement 2024+ 进阶

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
<!-- BOM 引用(Bill of Materials)-->
<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-dependencies</artifactId>
            <version>3.4.0</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-alibaba-dependencies</artifactId>
            <version>2023.0.1.0</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>

Maven Wrapper 的 2024+ 变化

1
2
3
4
5
# 旧版(Takari wrapper)
mvn -N io.takari:maven:0.7.7:wrapper -Dmaven=3.9.6

# 新版(Maven 官方 wrapper 3.2+)
mvn wrapper:wrapper -Dmaven=3.9.9

新版 wrapper 由 Maven 官方维护,不需要 Takari 仓库

依赖冲突排查的 2024+ 新工具

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
# 1. mvn dependency:tree(老牌)
mvn dependency:tree -Dverbose -Dincludes=commons-logging:commons-logging

# 2. maven-dependency-plugin 3.6+:dependency:analyze
mvn dependency:analyze

# 3. Enforcer 插件:禁止某些依赖
<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-enforcer-plugin</artifactId>
    <version>3.4.1</version>
</plugin>

实战坑(2024+)

  • Spring Boot 3.x 必须 JDK 17+——Maven 3.8.x 之前的版本不支持 --add-opens,需用 3.9.x
  • Maven Central 在 2024-06 调整了 HTTPS 证书链——老 Maven 版本(< 3.6.3)需升级
  • Nexus 3.64+ 强制 HTTPS——HTTP 私服要升级或保留 HTTP 白名单
  • JCenter 2022 已停止服务——所有 jcenter() 引用要改 mavenCentral()

2024+ 推荐组合

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
企业 Java 项目Spring Boot 3.x
├── Maven 3.9.x / Maven 4.02024+
├── 阿里云镜像 + settings.xml
├── Maven Wrapper 3.2+
├── spring-boot-starter-parent 3.4.x
├── spring-cloud-dependencies 2024.0.x BOM
├── spring-cloud-alibaba-dependencies 2023.0.x BOM
├──  POM dependencyManagement 统一版本
├──  POM 引用无版本号
├── Nexus 3.64+ 私服maven-releases + maven-snapshots
└── mvn -Pprod clean package + Jib  Docker 镜像
使用 Hugo 构建
主题 StackJimmy 设计