Maven
Apache Maven —— Java 项目构建与依赖管理工具
简介
Maven 是 Apache 基金会出品的项目构建和依赖管理工具,使用 POM(Project Object Model) 描述项目配置,提供标准化的构建流程。
核心功能
| 功能 | 说明 |
|---|---|
| 依赖管理 | 自动下载和管理项目依赖的第三方库 |
| 标准化构建 | 统一的目录结构和生命周期 |
| 插件化 | 通过插件扩展构建能力 |
| 继承与聚合 | 多模块项目父子继承、模块聚合 |
| 仓库管理 | 本地仓库 + 中央仓库 + 私有仓库 |
Maven vs 其他构建工具
| 特性 | Maven | Gradle | Ant |
|---|---|---|---|
| 配置文件 | XML(POM) | Groovy/Kotlin DSL | XML |
| 依赖管理 | 内置 | 内置 | 无 |
| 约定优先 | 是 | 是 | 否 |
| 性能 | 较慢 | 快(增量构建) | 快 |
| 自定义 | 插件 | 灵活 | 最灵活 |
| 学习曲线 | 平缓 | 较陡 | 简单 |
安装
前置要求
- JDK 8 或更高版本
Windows
- 下载二进制包:https://maven.apache.org/download.cgi(
apache-maven-3.9.x-bin.zip) - 解压到指定目录,如
D:\apache-maven-3.9.9 - 配置环境变量:
- MAVEN_HOME =
D:\apache-maven-3.9.9 - PATH 追加
%MAVEN_HOME%\bin
- MAVEN_HOME =
- 验证安装:
mvn --version输出示例:
Apache Maven 3.9.9 (8e8579a9e76f7d015ee5ec7bfcdc97d260186937)
Maven home: D:\apache-maven-3.9.9
Java version: 21.0.2, vendor: Oracle Corporation
Java home: C:\Program Files\Java\jdk-21macOS
brew install mavenLinux
# Ubuntu / Debian
sudo apt install maven
# CentOS / RHEL
sudo yum install maven目录结构
Maven 约定了标准的项目目录结构:
project/
├── pom.xml ← 项目对象模型(核心配置文件)
├── src/
│ ├── main/
│ │ ├── java/ ← Java 源代码
│ │ ├── resources/ ← 资源文件(配置文件、XML 等)
│ │ └── webapp/ ← Web 应用文件(仅 WAR 项目)
│ │ ├── WEB-INF/
│ │ └── index.html
│ └── test/
│ ├── java/ ← 测试代码
│ └── resources/ ← 测试资源
└── target/ ← 构建输出目录(编译后的 class、打包的 JAR/WAR)POM 详解
POM(Project Object Model)是 Maven 的核心配置文件,以下是常用配置:
<?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-app</artifactId>
<version>1.0.0</version>
<packaging>jar</packaging> <!-- jar / war / pom -->
<!-- 项目信息 -->
<name>My App</name>
<description>示例项目</description>
<url>https://example.com</url>
<!-- 属性 -->
<properties>
<maven.compiler.source>21</maven.compiler.source>
<maven.compiler.target>21</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<junit.version>5.11.0</junit.version>
</properties>
<!-- 依赖 -->
<dependencies>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
<version>${junit.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.17.2</version>
</dependency>
</dependencies>
<!-- 构建配置 -->
<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>
</configuration>
</plugin>
</plugins>
</build>
</project>坐标(Coordinates)
| 元素 | 说明 | 示例 |
|---|---|---|
| groupId | 组织/公司标识(反向域名) | com.example、org.springframework.boot |
| artifactId | 项目/模块名称 | my-app、spring-boot-starter-web |
| version | 版本号 | 1.0.0、3.3.2 |
| packaging | 打包方式(默认 jar) | jar、war、pom |
依赖范围(scope)
| scope | 说明 | 编译 | 测试 | 运行 | 示例 |
|---|---|---|---|---|---|
| compile(默认) | 所有阶段可用 | ✓ | ✓ | ✓ | Spring、Jackson |
| provided | 运行时由 JDK 或容器提供 | ✓ | ✓ | ✗ | Servlet API、Lombok |
| runtime | 编译不需要,运行需要 | ✗ | ✓ | ✓ | JDBC 驱动 |
| test | 仅测试阶段 | ✗ | ✓ | ✗ | JUnit、Mockito |
| system | 类似 provided,显式指定路径 | ✓ | ✓ | ✗ | 极少使用 |
依赖传递
Maven 会自动拉取依赖项的依赖(传递依赖),可通过 <exclusions> 排除不需要的传递依赖:
<dependency>
<groupId>com.example</groupId>
<artifactId>some-lib</artifactId>
<version>1.0</version>
<exclusions>
<exclusion>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-simple</artifactId>
</exclusion>
</exclusions>
</dependency>依赖冲突原则
当同一个依赖出现多个版本时,Maven 按以下规则选择:
- 最短路径优先 — 路径短的版本胜出
- 最先声明优先 — 路径相同,先声明的版本胜出
常用命令
| 命令 | 说明 |
|---|---|
mvn clean | 删除 target 目录 |
mvn compile | 编译源代码 |
mvn test | 运行测试 |
mvn package | 打包(生成 JAR/WAR) |
mvn install | 安装到本地仓库 |
mvn deploy | 部署到远程仓库 |
mvn validate | 验证项目配置是否正确 |
mvn verify | 验证包是否有效且符合质量要求 |
mvn site | 生成项目文档 |
mvn clean install | 最常用:清理 + 编译 + 测试 + 打包 + 安装 |
常用参数
# 跳过测试
mvn package -DskipTests
# 跳过测试编译和执行
mvn package -Dmaven.test.skip=true
# 指定配置文件
mvn clean install -P production
# 离线模式(不从远程仓库下载)
mvn clean install -o
# 指定 settings.xml 路径
mvn clean install -s /path/to/settings.xml
# 调试输出
mvn clean install -X
# 仅编译特定模块(多模块项目)
mvn clean install -pl module-name
# 同时构建依赖模块
mvn clean install -pl module-name -am生命周期
Maven 有三套相互独立的生命周期,每套包含多个阶段(phase):
Default(默认生命周期)
validate → 验证项目配置
↓
initialize → 初始化构建状态
↓
generate-sources → 生成源代码
↓
process-sources → 处理源代码
↓
generate-resources → 生成资源文件
↓
process-resources → 复制资源文件到目标目录
↓
compile → 编译源代码
↓
process-classes → 处理编译后的 class 文件
↓
generate-test-sources → 生成测试源代码
↓
process-test-sources → 处理测试源代码
↓
test-compile → 编译测试代码
↓
process-test-classes → 处理测试 class 文件
↓
test → 运行测试
↓
prepare-package → 打包前的准备
↓
package → 打包(JAR/WAR)
↓
verify → 验证包
↓
install → 安装到本地仓库
↓
deploy → 部署到远程仓库Clean 生命周期
pre-clean → clean → post-cleanSite 生命周期
pre-site → site(生成文档) → post-site → site-deploy仓库
仓库类型
Maven 仓库
├── 本地仓库(Local)
│ └── ${user.home}/.m2/repository/
├── 中央仓库(Central)
│ └── https://repo.maven.apache.org/maven2/
└── 远程仓库(Remote / Private)
├── 私有仓库(Nexus、Artifactory、Archiva)
└── 镜像仓库(阿里云、华为云)配置阿里云镜像
在 settings.xml 中添加镜像:
<mirrors>
<mirror>
<id>aliyunmaven</id>
<mirrorOf>central</mirrorOf>
<name>阿里云公共仓库</name>
<url>https://maven.aliyun.com/repository/public</url>
</mirror>
</mirrors>配置私有仓库(pom.xml)
<repositories>
<repository>
<id>my-private-repo</id>
<url>https://nexus.example.com/repository/maven-releases/</url>
<releases>
<enabled>true</enabled>
</releases>
<snapshots>
<enabled>true</enabled>
</snapshots>
</repository>
</repositories>配置认证(settings.xml)
<servers>
<server>
<id>my-private-repo</id>
<username>deploy-user</username>
<password>encrypted-password</password>
</server>
</servers>settings.xml
settings.xml 是 Maven 的全局/用户配置文件:
配置位置
| 位置 | 路径 | 作用域 |
|---|---|---|
| 全局 | MAVEN_HOME/conf/settings.xml | 所有用户 |
| 用户 | ${user.home}/.m2/settings.xml | 当前用户(优先级更高) |
常用配置
<?xml version="1.0" encoding="UTF-8"?>
<settings xmlns="http://maven.apache.org/SETTINGS/1.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0
https://maven.apache.org/xsd/settings-1.0.0.xsd">
<!-- 本地仓库路径(默认: ${user.home}/.m2/repository) -->
<localRepository>D:/maven/repository</localRepository>
<!-- 镜像配置 -->
<mirrors>
<mirror>
<id>aliyun</id>
<name>阿里云 Maven 镜像</name>
<url>https://maven.aliyun.com/repository/public</url>
<mirrorOf>central</mirrorOf>
</mirror>
</mirrors>
<!-- 全局 JDK 版本 -->
<profiles>
<profile>
<id>jdk-21</id>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
<properties>
<maven.compiler.source>21</maven.compiler.source>
<maven.compiler.target>21</maven.compiler.target>
</properties>
</profile>
</profiles>
</settings>多模块项目
统一版本管理
多模块项目中,保证所有模块使用一致的依赖版本至关重要。
方式一:properties + dependencyManagement(推荐)
<!-- parent/pom.xml -->
<project>
<groupId>com.example</groupId>
<artifactId>parent-project</artifactId>
<version>1.0.0</version>
<packaging>pom</packaging>
<modules>
<module>common</module>
<module>service</module>
<module>web</module>
</modules>
<!-- 统一版本属性 -->
<properties>
<java.version>21</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-boot.version>3.3.2</spring-boot.version>
<mybatis-plus.version>3.5.8</mybatis-plus.version>
<hutool.version>5.8.32</hutool.version>
<jackson.version>2.17.2</jackson.version>
<lombok.version>1.18.34</lombok.version>
</properties>
<!-- 统一依赖版本管理(子模块无需声明版本号) -->
<dependencyManagement>
<dependencies>
<!-- Spring Boot BOM(引入即管理所有 Spring Boot 依赖) -->
<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>common</artifactId>
<version>${project.version}</version>
</dependency>
<!-- 第三方依赖 -->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-spring-boot3-starter</artifactId>
<version>${mybatis-plus.version}</version>
</dependency>
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>${hutool.version}</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>${jackson.version}</version>
</dependency>
</dependencies>
</dependencyManagement>
<!-- 所有子模块共用的依赖 -->
<dependencies>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>${lombok.version}</version>
<scope>provided</scope>
</dependency>
</dependencies>
</project>方式二:自定义 BOM 项目
规模更大的团队可以单独创建一个 BOM 项目,其他项目引用这个 BOM:
<!-- company-bom/pom.xml(独立的 BOM 项目) -->
<project>
<groupId>com.company</groupId>
<artifactId>company-bom</artifactId>
<version>1.0.0</version>
<packaging>pom</packaging>
<properties>
<spring-boot.version>3.3.2</spring-boot.version>
<spring-cloud.version>2023.0.3</spring-cloud.version>
</properties>
<dependencyManagement>
<dependencies>
<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>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
</project><!-- 业务项目引用 BOM -->
<project>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>com.company</groupId>
<artifactId>company-bom</artifactId>
<version>1.0.0</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
</project>方式三:${revision}(CI-Friendly 版本)
适用于频繁发布、需要 CI/CD 自动管理版本号的场景,只需在一个地方修改版本号。
父 POM 配置
<!-- parent/pom.xml -->
<project>
<groupId>com.example</groupId>
<artifactId>parent-project</artifactId>
<version>${revision}</version> <!-- 统一版本占位符 -->
<packaging>pom</packaging>
<modules>
<module>common</module>
<module>service</module>
<module>web</module>
</modules>
<properties>
<!-- 唯一版本定义(改这里即可) -->
<revision>1.0.0</revision>
<java.version>21</java.version>
<spring-boot.version>3.3.2</spring-boot.version>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>${spring-boot.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<!-- 内部模块引用同样使用 ${revision} -->
<dependency>
<groupId>com.example</groupId>
<artifactId>common</artifactId>
<version>${revision}</version>
</dependency>
</dependencies>
</dependencyManagement>
</project>模块 POM
<!-- common/pom.xml -->
<project>
<parent>
<groupId>com.example</groupId>
<artifactId>parent-project</artifactId>
<version>${revision}</version> <!-- 引用父 POM 的版本 -->
</parent>
<artifactId>common</artifactId>
<!-- 子模块无需再写 version,自动继承父 POM 的 ${revision} -->
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>
</project>构建与发布
# 本地开发(替换 ${revision} 为实际版本)
mvn clean install -Drevision=1.0.0
# CI/CD 打包(由流水线传入版本号)
mvn clean package -Drevision=1.0.0-SNAPSHOT
# 发布正式版本
mvn clean deploy -Drevision=1.0.0
# 发补丁版本
mvn clean deploy -Drevision=1.0.1flatten-maven-plugin(推荐)
直接使用 ${revision} 会导致安装到本地仓库的 POM 文件仍然包含 ${revision} 占位符,其他项目依赖时会解析失败。flatten-maven-plugin 负责在安装前将 POM 展平,将 ${revision} 替换为实际版本号。
<build>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>flatten-maven-plugin</artifactId>
<version>1.6.0</version>
<configuration>
<updatePomFile>true</updatePomFile>
<flattenMode>resolveCiFriendliesOnly</flattenMode>
</configuration>
<executions>
<execution>
<id>flatten</id>
<phase>process-resources</phase>
<goals>
<goal>flatten</goal>
</goals>
</execution>
<execution>
<id>flatten.clean</id>
<phase>clean</phase>
<goals>
<goal>clean</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>注意事项
| 要点 | 说明 |
|---|---|
| 子模块必须省略 version | 子模块 POM 中不要写 <version>,否则会覆盖 $ |
| IDEA 显示 ${revision} 不展开 | 正常现象,不影响构建,构建时 -Drevision=xxx 即可 |
| 发布插件需支持 | maven-release-plugin 从 3.0 起原生支持 $ |
| 第三方依赖引入 | 外部依赖的版本管理仍需放在 <dependencyManagement> 中统一管理 |
| git tag 建议 | CI/CD 中建议 git tag ${revision} 与发布的版本号保持一致 |
方式四:Maven 4 原生多模块版本管理
Maven 4 在 ${revision} 基础上进一步简化,通过 .mvn/ 目录和版本范围声明降低配置复杂度。
1. .mvn/maven.properties(集中定义版本)
将版本属性统一放到 .mvn/maven.properties 文件中,所有模块共享,无需在每个 POM 中重复声明 properties:
# .mvn/maven.properties
project.version=1.0.0
maven.compiler.source=21
maven.compiler.target=21
project.build.sourceEncoding=UTF-8
spring.boot.version=3.3.2
mybatis.plus.version=3.5.8该文件中的属性会自动注入到所有模块的构建过程中,效果等同于在 POM 的 <properties> 中定义。
2. 父 POM 引用 properties 文件中的属性
<!-- pom.xml (父 POM) -->
<project>
<groupId>com.example</groupId>
<artifactId>parent-project</artifactId>
<version>${project.version}</version> <!-- 从 .mvn/maven.properties 读取 -->
<packaging>pom</packaging>
<modules>
<module>common</module>
<module>service</module>
<module>web</module>
</modules>
<properties>
<!-- 引用 .mvn/maven.properties 中定义的属性 -->
<revision>${project.version}</revision>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>${spring.boot.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
</project>3. .mvn/maven.config(构建参数默认值)
# .mvn/maven.config
-Drevision=${project.version}
-DskipTests=false
--threads=4这样团队成员无需手动传入 -Drevision=xxx,构建时自动使用 maven.properties 中定义的值。
4. Maven 4 子模块 POM(简化写法)
Maven 4 支持无版本父引用,子模块 POM 可以省略父 POM 的 <version>:
<!-- common/pom.xml(Maven 4 版本) -->
<project>
<parent>
<groupId>com.example</groupId>
<artifactId>parent-project</artifactId>
<!-- 在 Maven 4 中,version 可选(从 .mvn/maven.properties 继承) -->
</parent>
<artifactId>common</artifactId>
<!-- 无需 version,自动继承 ${project.version} -->
</project>5. 构建与发布
# 本地构建(自动从 .mvn/maven.properties 读取版本)
mvn clean install
# 覆盖版本号发布
mvn clean deploy -Dproject.version=1.0.1
# 修改版本(只需改 .mvn/maven.properties 一个文件)
# project.version=1.1.0
mvn clean deploy与传统方式的对比
| 对比项 | Maven 3(${revision}) | Maven 4 原生方式 |
|---|---|---|
| 版本定义位置 | 父 POM 的 <properties> 中 | .mvn/maven.properties 统一文件 |
| 修改版本 | 改 POM 文件 | 改 .mvn/maven.properties(不影响 POM 结构) |
| flatten-plugin | 必需,否则 ${revision} 占位符残留 | 可选(Maven 4 安装时自动展平) |
| 子模块 POM | 父引用必须写 version | 父引用 version 可省略 |
| CI/CD 集成 | 需手动传 -Drevision=xxx | 从 .mvn/maven.config 自动读取 |
| 最低版本 | Maven 3.5+ | Maven 4.0+ |
目录结构
project/
├── .mvn/
│ ├── maven.properties ← 集中版本和属性定义
│ └── maven.config ← Maven 构建参数默认值
├── pom.xml ← 父 POM
├── common/
│ └── pom.xml ← 子模块(无需 version)
├── service/
│ └── pom.xml
└── web/
└── pom.xml模块 POM
<!-- common/pom.xml(子模块无需指定版本,由父 POM 统一管理) -->
<project>
<parent>
<groupId>com.example</groupId>
<artifactId>parent-project</artifactId>
<version>1.0.0</version>
</parent>
<artifactId>common</artifactId>
<dependencies>
<!-- 无需指定版本号,由父 POM 的 dependencyManagement 管理 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-spring-boot3-starter</artifactId>
</dependency>
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
</dependency>
</dependencies>
</project><!-- web/pom.xml(可执行模块,需要打包插件) -->
<project>
<parent>
<groupId>com.example</groupId>
<artifactId>parent-project</artifactId>
<version>1.0.0</version>
</parent>
<artifactId>web</artifactId>
<dependencies>
<dependency>
<groupId>com.example</groupId>
<artifactId>common</artifactId>
</dependency>
<dependency>
<groupId>com.example</groupId>
<artifactId>service</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>Profile(多环境配置)
Maven Profile 让同一套代码按不同环境(开发/测试/生产)使用不同的配置。
环境配置文件
按环境创建 properties 文件:
src/main/resources/
├── application.properties ← 公共配置
├── application-dev.properties ← 开发环境
├── application-test.properties ← 测试环境
└── application-prod.properties ← 生产环境配置 Profile
<!-- pom.xml -->
<project>
<profiles>
<!-- 开发环境(默认激活) -->
<profile>
<id>dev</id>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
<properties>
<env>dev</env>
<server.port>8080</server.port>
<db.url>jdbc:mysql://localhost:3306/dev_db</db.url>
<lombok.config>true</lombok.config>
</properties>
</profile>
<!-- 测试环境 -->
<profile>
<id>test</id>
<properties>
<env>test</env>
<server.port>8080</server.port>
<db.url>jdbc:mysql://192.168.1.100:3306/test_db</db.url>
</properties>
</profile>
<!-- 生产环境 -->
<profile>
<id>prod</id>
<properties>
<env>prod</env>
<server.port>8080</server.port>
<db.url>jdbc:mysql://10.0.0.1:3306/prod_db</db.url>
</properties>
</profile>
</profiles>
</project>结合资源过滤器
利用 Maven 资源过滤,在构建时替换配置文件中的占位符:
1. 配置资源过滤
<build>
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
<excludes>
<exclude>application-dev.properties</exclude>
<exclude>application-test.properties</exclude>
<exclude>application-prod.properties</exclude>
</excludes>
</resource>
</resources>
</build>2. 创建模板配置文件
# src/main/resources/application.properties
spring.profiles.active=@env@
server.port=@server.port@
spring.datasource.url=@db.url@@env@、@server.port@、@db.url@ 等占位符在构建时会被替换为 profile 中定义的属性值。
3. 使用 profile 打包
# 开发环境(默认)
mvn clean package
# 测试环境
mvn clean package -P test
# 生产环境
mvn clean package -P prod
# 生产环境 + 跳过测试
mvn clean package -P prod -DskipTestsprofile 包含多个模块的激活
在多模块项目中,可以在根 POM 的 profile 中控制哪些模块参与构建:
<profile>
<id>full</id>
<modules>
<module>common</module>
<module>service</module>
<module>web</module>
<module>admin</module>
<module>batch</module>
</modules>
</profile>
<profile>
<id>minimal</id>
<modules>
<module>common</module>
<module>web</module>
</modules>
</profile># 只构建 core 模块
mvn clean install -P minimal
# 构建全部模块
mvn clean install -P fullSpring Boot 多环境打包实战
结合 Spring Boot 的 spring-boot-maven-plugin:
<build>
<finalName>${project.artifactId}-${env}</finalName>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<mainClass>com.example.Application</mainClass>
</configuration>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>打包结果:
# mvn clean package -P dev → target/my-app-dev.jar
# mvn clean package -P test → target/my-app-test.jar
# mvn clean package -P prod → target/my-app-prod.jarprofile 激活方式
| 激活方式 | 示例 | 说明 |
|---|---|---|
| 默认激活 | <activeByDefault>true</activeByDefault> | 无参构建时生效 |
| 命令行 | -P test | 最常用方式 |
| 环境变量 | <activation><jdk>11</jdk></activation> | JDK 版本匹配时激活 |
| 系统属性 | <activation><property><name>env</name><value>prod</value></property></activation> | 系统属性匹配时激活 |
| 文件存在 | <activation><file><exists>config/prod.properties</exists></file></activation> | 文件存在时激活 |
常用插件
| 插件 | 说明 | 用途 |
|---|---|---|
| maven-compiler-plugin | 编译插件 | 配置 JDK 版本 |
| maven-surefire-plugin | 测试插件 | 运行 JUnit 测试 |
| maven-jar-plugin | JAR 打包 | 配置 Manifest |
| maven-war-plugin | WAR 打包 | Web 项目打包 |
| maven-assembly-plugin | 自定义打包 | 生成含依赖的 JAR |
| maven-shade-plugin | 阴影打包 | 合并依赖、重命名包名 |
| maven-source-plugin | 源码打包 | 生成 sources.jar |
| maven-javadoc-plugin | 文档打包 | 生成 javadoc.jar |
| maven-deploy-plugin | 部署 | 发布到远程仓库 |
| maven-release-plugin | 发布管理 | 自动化版本发布 |
| spring-boot-maven-plugin | Spring Boot | 可执行 JAR 打包 |
示例:Spring Boot 打包插件
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>3.3.2</version>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>示例:打包可执行 JAR(含依赖)
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<configuration>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
<archive>
<manifest>
<mainClass>com.example.Main</mainClass>
</manifest>
</archive>
</configuration>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>常见问题
依赖下载慢
配置阿里云镜像(见上方 settings.xml 配置)。
依赖冲突
# 查看依赖树
mvn dependency:tree
# 查看具体依赖的解析路径
mvn dependency:tree -Dincludes=com.fasterxml.jackson:jackson-databind
# 分析未使用/需声明的依赖
mvn dependency:analyzeJar 包未更新(缓存)
# 强制更新快照依赖
mvn clean install -U
# 删除本地仓库的特定依赖后重新下载
rm -rf ~/.m2/repository/com/example/some-lib/编译版本错误
确保以下配置一致:
<properties>
<maven.compiler.source>21</maven.compiler.source>
<maven.compiler.target>21</maven.compiler.target>
</properties>同时检查 JAVA_HOME 环境变量指向对应版本的 JDK。
最佳实践
- 统一版本管理 — 使用
<dependencyManagement>或 Spring Boot BOM 统一管理所有依赖版本 - 避免依赖重复 — 使用
<exclusions>排除冲突的传递依赖 - 模块划分 — 大型项目拆分为多模块,每个模块职责单一
- 明确依赖范围 — 测试依赖用
test,容器相关用provided - 标准化版本号 — 使用语义化版本(
主版本.次版本.修订号) - 忽略 target 目录 —
.gitignore中添加target/ - 使用 profiles — 按环境(开发/测试/生产)区分配置
- 定期更新 — 定期检查依赖版本更新,避免使用过旧的版本