构建过程中的执行顺序
- maven-compiler-plugin :编译源代码(compile阶段)所有插件:「前置基础」
- maven-jar-plugin/maven-war-plugin :打包编译后的class文件(package阶段)生成通 JAR/WAR
- maven-dependency-plugin :复制依赖项(package阶段)仅解决「依赖分析/分离」的辅助问题
- spring-boot-maven-plugin:增强maven
一、核心结论:无重复,是「分层协作」关系
这 5 个插件覆盖了 Maven 构建的编译 → 基础打包 → 增强打包 → 依赖管理 → 特殊打包 全链路,职责边界清晰,核心关系如下:
编译源码到class文件
生成普通JAR/WAR
增强为可执行JAR/WAR
可选:分离依赖/分析冲突
maven-compiler-plugin
maven-jar-plugin/maven-war-plugin
spring-boot-maven-plugin
最终产物
maven-dependency-plugin
简单来说:
- 基础构建层 :
maven-compiler-plugin(编译) +maven-jar/war-plugin(基础打包)是 Maven 原生核心,所有 Java 项目都依赖; - Spring Boot 增强层 :
spring-boot-maven-plugin基于基础打包产物做「二次加工」,不替代基础插件,而是增强其能力; - 辅助层 :
maven-dependency-plugin是「工具类插件」,按需使用(如分离依赖、排查冲突),不参与核心构建流程。
二、逐个拆解:插件间的协作/互补关系
1. maven-compiler-plugin ↔ 所有插件:「前置基础」
- 关系 :
maven-compiler-plugin是所有后续插件的前提,无编译就无后续打包; - 协作逻辑 :
- 它先将
src/main/java源码编译为target/classes下的 class 文件; - 无论是
maven-jar-plugin打包基础 JAR,还是spring-boot-maven-plugin构建可执行 JAR,都依赖编译后的 class 文件;
- 它先将
- 是否重复:❌ 无任何插件能替代它的「编译职责」,是构建的「第一关」。
2. maven-jar-plugin ↔ spring-boot-maven-plugin:「基础 → 增强」
这是你最关心的核心关系,用「两步打包」就能理解:
| 阶段 | 插件 | 产物 | 作用 |
|---|---|---|---|
| 第一步 | maven-jar-plugin | 普通 JAR(original-xxx.jar) | 仅打包 target/classes 的 class 文件 + 资源文件,无依赖、不可直接运行; |
| 第二步 | spring-boot-maven-plugin | 可执行 JAR(xxx.jar) | 读取普通 JAR,将所有依赖打包到 JAR 内部(BOOT-INF/lib),添加 Spring Boot 启动器、指定主类,使其可 java -jar 运行; |
- 关键细节 :
spring-boot-maven-plugin不会「重复打包」,而是基于maven-jar-plugin的产物做「重打包(repackage)」;- 即使你不显式配置
maven-jar-plugin,Spring Boot 父 POM 也会默认引入(版本与 Spring Boot 适配),保证基础打包流程; - 两者无冲突:
maven-jar-plugin负责「基础封装」,spring-boot-maven-plugin负责「Spring Boot 特性增强」。
3. maven-war-plugin ↔ spring-boot-maven-plugin:「替代/互补(按需选择)」
-
核心场景:两者都用于生成 WAR,但定位不同;
-
协作/替代关系 :
场景 插件选择 原因 Spring Boot 部署到外部 Tomcat maven-war-plugin + spring-boot-maven-plugin maven-war-plugin生成基础 WAR,spring-boot-maven-plugin增强为「可在外部容器运行的 Spring Boot WAR」(排除内置 Tomcat);传统 Web 项目(非 Spring Boot) 仅 maven-war-plugin 无需 Spring Boot 增强,原生 WAR 即可部署; Spring Boot 内置容器运行 仅 spring-boot-maven-plugin(打 JAR) 无需 WAR,可执行 JAR 更轻量; -
是否重复:❌ 仅在「Spring Boot 打 WAR」场景下配合使用,其余场景按需选择,无重复。
4. maven-dependency-plugin ↔ 其他插件:「可选辅助,无冲突」
- 核心定位 :它是「依赖管理工具」,不参与核心打包,而是按需补充功能;
- 与其他插件的配合场景 :
- 与
maven-jar-plugin配合:传统 Java 项目打普通 JAR 后,用它复制依赖到lib目录(实现「主 JAR + 外部依赖」分离打包); - 与
spring-boot-maven-plugin配合:非必需(Spring Boot 可执行 JAR 已内置依赖),仅在「分离依赖」场景下使用(如想把依赖放到外部目录,减小 JAR 体积); - 通用场景:无论哪种打包方式,都可用它分析依赖冲突(
dependency:tree)、清理本地依赖(dependency:purge-local-repository);
- 与
- 是否重复:❌ 无任何插件能替代它的「依赖分析/复制」能力,是「加分项」而非「必选项」。
三、关键场景:插件组合使用示例
场景 1:Spring Boot 标准打包(最常用)
- 核心插件:
maven-compiler-plugin+maven-jar-plugin+spring-boot-maven-plugin; - 无需
maven-dependency-plugin(Spring Boot 可执行 JAR 内置依赖); - 无需
maven-war-plugin(默认打 JAR); - 构建流程:
compiler编译源码 → 2.jar-plugin生成普通 JAR → 3.spring-boot-plugin重打包为可执行 JAR。
场景 2:Spring Boot 打 WAR(部署到外部 Tomcat)
- 核心插件:
maven-compiler-plugin+maven-war-plugin+spring-boot-maven-plugin; - 构建流程:
compiler编译源码 → 2.war-plugin生成普通 WAR → 3.spring-boot-plugin增强为可在外部 Tomcat 运行的 WAR(排除内置 Tomcat)。
场景 3:传统 Java 项目(非 Spring Boot)分离打包
- 核心插件:
maven-compiler-plugin+maven-jar-plugin+maven-dependency-plugin; - 无需
spring-boot-maven-plugin(无 Spring Boot 特性); - 构建流程:
compiler编译源码 → 2.jar-plugin生成普通 JAR → 3.dependency-plugin复制依赖到lib目录 → 最终产物:主 JAR + lib 依赖目录。
四、容易误解的「重复」场景及澄清
误解 1:spring-boot-maven-plugin 替代了 maven-jar-plugin?
❌ 不替代,而是「基于它加工」:
maven-jar-plugin生成的是「Maven 标准 JAR」(仅含自身 class/资源);spring-boot-maven-plugin的repackage目标,是把这个标准 JAR 重新打包为「Spring Boot 可执行 JAR」(内置依赖、启动器);- 即使你不写
maven-jar-plugin配置,Spring Boot 父 POM 也会自动引入它(版本适配),保证基础打包。
误解 2:maven-dependency-plugin 与 spring-boot-maven-plugin 重复(都处理依赖)?
❌ 处理方式完全不同:
spring-boot-maven-plugin:将依赖内置到可执行 JAR/WAR (BOOT-INF/lib),实现「单包运行」;maven-dependency-plugin:将依赖复制到外部目录 (如target/lib),实现「主包 + 外部依赖」分离;- 场景互补:Spring Boot 默认用「内置依赖」,如需分离依赖(如减小主包体积),才会配合
maven-dependency-plugin使用。
误解 3:maven-war-plugin 与 spring-boot-maven-plugin 重复(都打 WAR)?
❌ 目标不同:
maven-war-plugin:生成「传统 WAR」(仅含自身 class/资源,依赖需手动放WEB-INF/lib);spring-boot-maven-plugin增强后的 WAR:兼容传统 WAR 结构,同时保留 Spring Boot 特性(如自动配置、内置容器可选);- 仅在「Spring Boot 部署到外部 Tomcat」时配合使用,否则二选一(JAR 用 Spring Boot 插件,传统 WAR 用 maven-war-plugin)。
总结
- 无重复,是「分工协作」:5 个插件覆盖「编译 → 基础打包 → 增强打包 → 依赖管理」全流程,每个插件聚焦单一职责;
- 核心依赖链 :
compiler→jar/war→spring-boot-plugin是 Spring Boot 项目的核心链路,dependency-plugin是按需使用的辅助工具; - 关键边界 :
spring-boot-plugin不替代基础插件,而是「增强」其产物;dependency-plugin不参与核心打包,仅解决「依赖分析/分离」的辅助问题;war-plugin仅在「传统 Web/外部 Tomcat」场景与 Spring Boot 插件配合,否则无需使用。
maven-compiler-plugin
maven-compiler-plugin 是 Maven 官方核心插件,专门负责编译 Java 源码 (包括主源码和测试源码),是所有 Java 项目构建的基础插件(Maven 会默认引入,但建议显式配置版本和参数以避免兼容问题)。下面从核心定位、核心配置、常用 Goal、实战场景、避坑指南 五个维度,详细讲解这个插件的使用方式和关键细节。
简介
- 功能 :负责Java源代码的编译
- 作用 :在编译阶段执行,负责将 .java 源文件编译成 .class 字节码文件
- 将 .java 源文件编译成 .class 字节码文件
- 配置编译版本(如Java 8)、编码格式(如UTF-8)等编译参数
- 确保代码在编译时符合指定的Java版本要求
- 执行阶段 : compile 阶段(在构建过程中较早执行)
一、核心定位与基础认知
1. 核心作用
- 编译
src/main/java下的主源码到target/classes目录; - 编译
src/test/java下的测试源码到target/test-classes目录; - 指定 Java 编译版本(解决「源码使用高版本特性但编译环境版本低」的报错);
- 配置编码、编译器参数、依赖传递等编译规则。
2. 默认行为(未显式配置时)
- 默认使用 JDK 1.5 编译(极易导致高版本 Java 语法报错,如 Lambda、Stream);
- 默认编码为系统编码(Windows 下易出现中文乱码);
- 绑定到 Maven 生命周期的
compile(主源码)和test-compile(测试源码)阶段,执行mvn compile/package时自动触发。
二、核心配置详解(POM 完整示例)
xml
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.11.0</version> <!-- 稳定版,推荐指定(最新版可查Maven中央仓库) -->
<configuration>
<!-- 1. Java 版本配置(最核心) -->
<source>8</source> <!-- 源码兼容的 Java 版本(如 8/11/17),等价于 javac -source -->
<target>8</target> <!-- 生成的 class 文件兼容的 Java 版本,等价于 javac -target -->
<release>8</release> <!-- Java 9+ 推荐用:同时指定 source 和 target,更简洁(二选一) -->
<!-- 2. 编码配置(解决中文乱码) -->
<encoding>UTF-8</encoding>
<!-- 3. 编译器参数(可选) -->
<compilerArgs>
<arg>-Xlint:unchecked</arg> <!-- 开启未检查类型警告 -->
<arg>-Xlint:deprecation</arg> <!-- 开启过期API警告 -->
<arg>-g</arg> <!-- 生成调试信息(便于断点调试) -->
</compilerArgs>
<!-- 4. 源码/测试源码目录(默认无需修改,特殊目录时配置) -->
<sourceDirectory>src/main/java</sourceDirectory>
<testSourceDirectory>src/test/java</testSourceDirectory>
<!-- 5. 编译跳过/包含/排除 -->
<skip>false</skip> <!-- 是否跳过编译(true 则不编译,慎用) -->
<includes>
<include>**/*.java</include> <!-- 包含的文件(默认所有.java) -->
</includes>
<excludes>
<exclude>**/temp/*.java</exclude> <!-- 排除临时目录的源码 -->
</excludes>
<!-- 6. 其他优化配置 -->
<showWarnings>true</showWarnings> <!-- 显示编译警告 -->
<showDeprecation>true</showDeprecation> <!-- 显示过期API警告 -->
<fork>true</fork> <!-- 启用独立进程编译(避免类加载冲突,推荐true) -->
<meminitial>128m</meminitial> <!-- 编译进程初始内存 -->
<maxmem>512m</maxmem> <!-- 编译进程最大内存(解决大项目编译OOM) -->
</configuration>
</plugin>
</plugins>
</build>
三、关键配置参数说明
| 参数名 | 作用 | 常用值 | 注意事项 |
|---|---|---|---|
source/target |
指定源码/字节码兼容版本 | 8/11/17 | Java 9+ 推荐用 release 替代(更简洁) |
release |
Java 9+ 专属:同时设置 source 和 target,保证版本一致性 | 8/11/17 | 不能与 source/target 同时配置 |
encoding |
指定源码编译编码 | UTF-8 | 必须配置,否则中文注释/字符串会乱码 |
fork |
是否启用独立进程编译 | true | 推荐设为 true,避免 Maven 自身类加载冲突 |
meminitial/maxmem |
编译进程的初始/最大内存 | 128m/512m | 大项目编译OOM时增大该值 |
compilerArgs |
传递给 javac 的额外参数(如警告级别、调试信息) | -Xlint:unchecked | 多个参数用 <arg> 逐个配置 |
skip |
跳过编译(主源码+测试源码) | false | 仅临时调试时设为 true,发布时必须设为 false |
testSkip |
仅跳过测试源码编译(主源码仍编译) | false | 比 skip 更精细,适合无需测试的场景 |
四、常用 Goal(目标)
maven-compiler-plugin 的 Goal 较少,但都是构建的核心,且默认绑定到生命周期,无需手动执行:
| Goal | 作用 | 触发方式 |
|---|---|---|
compiler:compile |
编译主源码(src/main/java),绑定到 compile 阶段 |
mvn compile / mvn package(自动) |
compiler:testCompile |
编译测试源码(src/test/java),绑定到 test-compile 阶段 |
mvn test-compile / mvn test(自动) |
compiler:help |
查看插件帮助(含参数说明) | mvn compiler:help -Ddetail=true |
五、典型实战场景
场景 1:基础配置(解决90%的编译问题)
需求:Java 8 项目,解决中文乱码+指定编译版本+显示警告。
xml
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.11.0</version>
<configuration>
<source>8</source>
<target>8</target>
<encoding>UTF-8</encoding>
<showWarnings>true</showWarnings>
<fork>true</fork>
</configuration>
</plugin>
场景 2:Java 17 项目(用 release 简化配置)
xml
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.11.0</version>
<configuration>
<release>17</release> <!-- 替代 source + target,Java 9+ 推荐 -->
<encoding>UTF-8</encoding>
<compilerArgs>
<arg>--enable-preview</arg> <!-- 启用 Java 预览特性(可选) -->
</compilerArgs>
</configuration>
</plugin>
场景 3:解决大项目编译 OOM 问题
xml
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.11.0</version>
<configuration>
<source>8</source>
<target>8</target>
<encoding>UTF-8</encoding>
<fork>true</fork> <!-- 必须开启独立进程,否则内存配置无效 -->
<meminitial>256m</meminitial>
<maxmem>1024m</maxmem> <!-- 增大最大内存 -->
</configuration>
</plugin>
场景 4:跳过测试源码编译(仅编译主源码)
xml
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.11.0</version>
<configuration>
<source>8</source>
<target>8</target>
<encoding>UTF-8</encoding>
<testSkip>true</testSkip> <!-- 跳过测试源码编译 -->
</configuration>
</plugin>
六、常见问题与避坑指南
问题 1:编译报错「不支持 lambda 表达式」
- 原因:默认用 JDK 1.5 编译,不支持高版本语法;
- 解决方案:显式配置
source/target为 8+。
问题 2:编译后中文注释/字符串乱码
- 原因:编码未配置,使用系统默认编码(如 GBK);
- 解决方案:添加
<encoding>UTF-8</encoding>。
问题 3:编译报「无效的目标发行版: 17」
- 原因:本地 Maven 运行的 JDK 版本低于配置的
source/target/release; - 解决方案:
- 确认本地 JDK 版本 ≥ 配置的版本;
- 配置
MAVEN_OPTS指定 JDK 路径,或在 IDE 中指定 Maven 运行的 JDK。
问题 4:编译大项目报 OutOfMemoryError
- 原因:编译进程内存不足;
- 解决方案:开启
fork=true,并增大meminitial/maxmem。
总结
- 核心价值 :
maven-compiler-plugin是 Java 项目编译的基础,最关键的配置是「Java 版本」和「编码」,必须显式配置以避免兼容问题; - 版本配置 :Java 8 用
source + target,Java 9+ 推荐用release简化配置; - 必配项 :
encoding=UTF-8+fork=true是所有项目的基础配置,可解决编码和类加载冲突问题; - 避坑重点:编译报错优先检查 Java 版本、编码、JDK 运行环境三者是否一致;
- 优化配置 :大项目需调整编译内存(
meminitial/maxmem),测试场景可跳过测试源码编译(testSkip=true)。
maven-jar-plugin 和 maven-war-plugin
maven-jar-plugin 和 maven-war-plugin 是 Maven 官方核心打包插件,分别用于构建 JAR 包 (纯 Java 项目/后端模块)和 WAR 包 (Web 项目),两者核心目标都是「打包项目产物」,但适配不同项目类型,下面从核心定位、核心配置、常用 Goal、实战示例、关键差异 五个维度详细讲解,方便你按需使用。
简介
jar
- 功能 :负责将编译后的class文件和资源文件打包成jar文件
- 作用 :在打包阶段执行,将编译后的 class 文件和资源文件打包成 JAR 文件
- 生成包含项目代码和资源的jar文件
- 配置jar文件的清单文件(MANIFEST.MF),如指定主类、类路径等
- 控制jar文件的内容和结构
- 执行阶段 : package 阶段(在编译后执行)
war
- 是专门用于生成 WAR 文件的插件,适用于传统的 Java Web 应用项目
- 作用 :在打包阶段执行,将 Web 应用的资源、类文件和依赖项打包成 WAR 文件
- 生成 WAR 文件 :
- 将 Web 应用的资源、类文件和依赖项打包成标准的 WAR 文件格式
- WAR 文件是 Java Web 应用的部署单元,包含了应用的所有内容
- 配置 WAR 文件内容 :
- 控制哪些文件和目录包含在 WAR 文件中
- 配置 Web 应用的目录结构,如 WEB-INF/classes、WEB-INF/lib 等
- 处理 web.xml :
- 支持配置 web.xml 文件的位置和内容
- 可以设置当缺少 web.xml 时是否失败(如 false )
- 自定义 WAR 文件名 :
- 通过 配置 WAR 文件的名称
- 依赖项处理 :
- 将项目依赖项复制到 WAR 文件的 WEB-INF/lib 目录中
- 支持排除特定依赖项
- 生成 WAR 文件 :
- 执行阶段 : package 阶段(在编译后执行)
一、核心定位与适用场景
| 插件 | 核心定位 | 适用项目类型 | 打包产物结构 |
|---|---|---|---|
maven-jar-plugin |
构建标准 JAR 包(Java Archive) | 纯 Java 项目、后端工具类、微服务模块、非 Web 项目 | 包含编译后的 class 文件、资源文件(resources),无 Web 特有目录 |
maven-war-plugin |
构建 Web 应用包(Web Application Archive) | Spring MVC、Servlet、JSP 等 Web 项目 | 包含 WEB-INF(class、lib、web.xml)、META-INF、静态资源(html/css/js)等 Web 标准结构 |
二、maven-jar-plugin 详细讲解
1. 核心作用
- 编译项目源码后,将
target/classes(class 文件+资源)打包为标准 JAR 包; - 支持自定义 JAR 文件名、MANIFEST.MF 配置(如指定主类、依赖路径);
- 支持过滤/包含/排除特定文件,适配不同打包需求。
2. 基础配置(POM 引入)
xml
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>3.4.0</version> <!-- 稳定版,推荐指定 -->
<configuration>
<!-- 核心配置项 -->
<finalName>my-app</finalName> <!-- 打包后的 JAR 名(默认:artifactId-version) -->
<archive> <!-- MANIFEST.MF 配置(最核心) -->
<manifest>
<addClasspath>true</addClasspath> <!-- 自动添加依赖类路径到 MANIFEST -->
<classpathPrefix>lib/</classpathPrefix> <!-- 依赖存放目录(配合依赖复制插件) -->
<mainClass>com.example.App</mainClass> <!-- 可执行 JAR 的主类(关键) -->
<useUniqueVersions>false</useUniqueVersions> <!-- 依赖版本是否省略(简化路径) -->
</manifest>
<manifestEntries> <!-- 自定义 MANIFEST 条目 -->
<Author>dev-team</Author>
<Build-Time>${maven.build.timestamp}</Build-Time>
</manifestEntries>
</archive>
<!-- 文件过滤 -->
<includes>
<include>**/*.class</include>
<include>**/*.yml</include>
</includes>
<excludes>
<exclude>**/*.log</exclude>
</excludes>
</configuration>
</plugin>
</plugins>
</build>
3. 常用 Goal
| Goal | 作用 | 常用命令 |
|---|---|---|
jar:jar |
核心 Goal:打包生成 JAR 包(默认绑定到 package 阶段) |
mvn jar:jar(手动执行)/ mvn package(自动执行) |
jar:test-jar |
打包测试源码为测试 JAR 包(如 my-app-test.jar) |
mvn jar:test-jar |
jar:help |
查看插件帮助(含参数说明) | mvn jar:help -Ddetail=true |
4. 实战场景
场景 1:构建可执行 JAR(最常用)
需求:打包后可通过 java -jar my-app.jar 直接运行。
xml
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>3.4.0</version>
<configuration>
<archive>
<manifest>
<mainClass>com.example.Main</mainClass> <!-- 必须指定主类 -->
<addClasspath>true</addClasspath>
<classpathPrefix>lib/</classpathPrefix>
</manifest>
</archive>
</configuration>
</plugin>
<!-- 配合依赖复制插件,将依赖复制到 lib 目录 -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<version>3.6.1</version>
<executions>
<execution>
<id>copy-deps</id>
<phase>package</phase>
<goals><goal>copy-dependencies</goal></goals>
<configuration>
<outputDirectory>${project.build.directory}/lib</outputDirectory>
<includeScope>runtime</includeScope>
</configuration>
</execution>
</executions>
</plugin>
执行 mvn package 后,target 下生成:
my-app.jar(可执行主包);lib目录(所有运行时依赖);
运行命令:java -jar target/my-app.jar。
场景 2:排除无用文件(减小 JAR 体积)
xml
<configuration>
<excludes>
<exclude>**/*.xml</exclude> <!-- 排除所有 xml 文件 -->
<exclude>**/test/*</exclude> <!-- 排除 test 目录 -->
</excludes>
</configuration>
三、maven-war-plugin 详细讲解
1. 核心作用
- 构建符合 Web 标准的 WAR 包(适配 Tomcat/Jetty 等 Servlet 容器);
- 自动整合 Web 资源(
src/main/webapp)、编译后的 class 文件、依赖包; - 支持自定义 WAR 结构、覆盖 web.xml、指定 Web 资源目录等。
2. 基础配置(POM 引入)
xml
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>3.4.0</version> <!-- 稳定版 -->
<configuration>
<warName>my-webapp</warName> <!-- 打包后的 WAR 名(默认:artifactId-version) -->
<webappDirectory>${project.build.directory}/my-webapp</webappDirectory> <!-- 解压后的 Web 目录(可选) -->
<warSourceDirectory>src/main/webapp</warSourceDirectory> <!-- Web 资源根目录(默认) -->
<webXml>src/main/webapp/WEB-INF/web.xml</webXml> <!-- web.xml 路径(默认) -->
<!-- 依赖打包配置:指定依赖放入 WEB-INF/lib 或提供外部依赖 -->
<dependentWarExcludes>**/log4j*.jar</dependentWarExcludes> <!-- 排除依赖 -->
<packagingExcludes>WEB-INF/lib/*.jar</packagingExcludes> <!-- 排除 WEB-INF/lib 下所有 jar(外部依赖) -->
<!-- 覆盖/添加 web.xml 配置(适用于无 web.xml 的注解式 Web 项目) -->
<failOnMissingWebXml>false</failOnMissingWebXml> <!-- 无 web.xml 时不报错(Spring Boot 常用) -->
</configuration>
</plugin>
</plugins>
</build>
3. 常用 Goal
| Goal | 作用 | 常用命令 |
|---|---|---|
war:war |
核心 Goal:打包生成 WAR 包(默认绑定到 package 阶段) |
mvn war:war / mvn package |
war:exploded |
解压 WAR 包到指定目录(不生成压缩包,便于本地调试) | mvn war:exploded(输出到 target/my-webapp) |
war:help |
查看插件帮助 | mvn war:help -Ddetail=true |
4. 实战场景
场景 1:Spring MVC 项目打包 WAR(传统 Web 项目)
xml
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>3.4.0</version>
<configuration>
<warName>spring-mvc-app</warName>
<webXml>src/main/webapp/WEB-INF/web.xml</webXml>
<!-- 排除测试依赖 -->
<packagingExcludes>WEB-INF/lib/junit*.jar,WEB-INF/lib/mockito*.jar</packagingExcludes>
</configuration>
</plugin>
执行 mvn package 后,target/spring-mvc-app.war 可直接部署到 Tomcat 的 webapps 目录。
场景 2:Spring Boot 打包 WAR(无 web.xml)
Spring Boot 项目默认打 JAR 包,如需打 WAR 包(部署到外部 Tomcat):
xml
<!-- 1. 修改打包类型为 war -->
<packaging>war</packaging>
<!-- 2. 排除内置 Tomcat(外部容器运行) -->
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<scope>provided</scope>
</dependency>
</dependencies>
<!-- 3. 配置 war 插件(无 web.xml 不报错) -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>3.4.0</version>
<configuration>
<failOnMissingWebXml>false</failOnMissingWebXml> <!-- 关键:无 web.xml 不报错 -->
<warName>spring-boot-web</warName>
</configuration>
</plugin>
四、核心差异对比
| 维度 | maven-jar-plugin | maven-war-plugin |
|---|---|---|
| 打包产物 | JAR 包(*.jar) |
WAR 包(*.war) |
| 适配项目 | 非 Web 项目(工具类、微服务、后台任务) | Web 项目(Servlet/JSP/Spring MVC) |
| 核心目录 | 无特有目录,仅包含 class + 资源 | 包含 WEB-INF(class/lib/web.xml)、META-INF、静态资源 |
| 关键配置 | manifest(主类、依赖路径) |
webXml、failOnMissingWebXml、packagingExcludes |
| 运行方式 | java -jar 直接运行 |
部署到 Servlet 容器(Tomcat/Jetty)运行 |
总结
- maven-jar-plugin :
- 核心是打包 JAR 包,重点配置
manifest指定主类实现可执行 JAR; - 配合
maven-dependency-plugin复制依赖到lib目录,是 Java 项目打包的基础;
- 核心是打包 JAR 包,重点配置
- maven-war-plugin :
- 核心是打包 WAR 包,适配 Web 项目,重点配置
webXml和failOnMissingWebXml; - Spring Boot 打 WAR 包需排除内置 Tomcat,设置
failOnMissingWebXml=false;
- 核心是打包 WAR 包,适配 Web 项目,重点配置
- 两者均默认绑定到
package阶段,执行mvn package即可自动打包,无需手动执行 Goal; - 自定义打包文件名用
finalName(jar 插件)/warName(war 插件),可统一产物命名规范。
maven-dependency-plugin
maven-dependency-plugin 是 Maven 官方核心插件之一,专门用于管理、分析和操作项目依赖(如下载依赖、查看依赖树、复制依赖到指定目录、分析依赖冲突等)。它覆盖了依赖生命周期的全场景,是解决 Maven 依赖问题的核心工具,下面从「核心功能」「常用目标(Goal)」「实战配置示例」「典型使用场景」四个维度详细讲解。
简介
- 功能 :负责依赖项的管理和处理
- 作用 :在打包阶段执行,将依赖项复制到指定目录(如 lib 目录)
- 复制依赖项到指定目录(如 lib 目录)
- 分析项目依赖关系
- 解决依赖冲突等问题
- 执行阶段 : 在 package 阶段中执行,通常在 JAR/WAR 打包之后
一、插件核心定位
- 核心作用:脱离 Maven 默认构建流程,主动操作依赖(查询、复制、解析、清理等);
- 适用场景 :
- 排查依赖冲突(如 jar 包版本冲突);
- 打包时将依赖复制到指定目录(如
lib文件夹); - 下载依赖到本地(无需构建项目);
- 分析项目依赖树、未使用依赖、过时依赖等。
二、插件基础配置
先看插件的基础引入方式(建议指定稳定版本,避免默认版本兼容问题):
xml
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<version>3.6.1</version> <!-- 最新稳定版,可查 Maven 中央仓库 -->
<!-- 全局配置(所有 Goal 共享) -->
<configuration>
<outputDirectory>${project.build.directory}/lib</outputDirectory> <!-- 依赖输出目录 -->
<excludeTransitive>false</excludeTransitive> <!-- 是否排除传递依赖 -->
<overWriteReleases>false</overWriteReleases> <!-- 是否覆盖正式版依赖 -->
<overWriteSnapshots>true</overWriteSnapshots> <!-- 是否覆盖快照版依赖 -->
</configuration>
</plugin>
</plugins>
</build>
三、核心 Goal 详解(按使用频率排序)
maven-dependency-plugin 的所有功能都通过「Goal」触发(可通过 mvn dependency:<goal> 命令执行),以下是最常用的 Goal:
1. dependency:tree(依赖树分析,最常用)
-
作用:生成项目的依赖树,展示所有直接/间接依赖,标注依赖冲突(如版本覆盖);
-
核心用途:排查依赖冲突、确认依赖来源;
-
常用命令 :
bash# 基础用法:生成依赖树 mvn dependency:tree # 过滤指定依赖(如只看 spring-core 相关) mvn dependency:tree -Dincludes=org.springframework:spring-core # 排除指定依赖(如排除 commons-lang3) mvn dependency:tree -Dexcludes=org.apache.commons:commons-lang3 # 输出到文件 mvn dependency:tree -Doutput=dependency-tree.txt # 显示详细冲突信息 mvn dependency:tree -Dverbose -
输出示例解读 :
[INFO] com.example:my-project:jar:1.0.0 [INFO] +- org.springframework:spring-core:jar:5.3.20:compile [INFO] | \- org.springframework:spring-jcl:jar:5.3.20:compile [INFO] +- commons-lang:commons-lang:jar:2.6:compile [INFO] \- org.apache.commons:commons-lang3:jar:3.12.0:compile (version managed from 3.10.0)(version managed from 3.10.0):表示版本被dependencyManagement覆盖;omitted for conflict with 2.6:表示依赖冲突,低版本被排除。
2. dependency:copy-dependencies(复制依赖到指定目录)
-
作用 :将项目所有依赖(直接+间接)复制到指定目录(如
target/lib); -
核心用途 :打包时将依赖和主 jar 包放在同一目录,方便运行(如
java -jar时指定classpath); -
常用配置 :
xml<plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-dependency-plugin</artifactId> <version>3.6.1</version> <executions> <execution> <id>copy-dependencies</id> <phase>package</phase> <!-- 绑定到 package 阶段,打包时自动复制 --> <goals> <goal>copy-dependencies</goal> </goals> <configuration> <outputDirectory>${project.build.directory}/lib</outputDirectory> <excludeGroupIds>junit,org.mockito</excludeGroupIds> <!-- 排除测试依赖 --> <includeScope>runtime</includeScope> <!-- 只复制运行时依赖(排除 test/provided) --> <useBaseVersion>true</useBaseVersion> <!-- 文件名使用基础版本(如 3.12.0 而非 3.12.0-SNAPSHOT) --> </configuration> </execution> </executions> </plugin> -
常用命令(手动执行) :
bashmvn dependency:copy-dependencies -DoutputDirectory=./lib -DincludeScope=runtime
3. dependency:resolve(解析并列出所有依赖)
-
作用:解析项目所有依赖,输出依赖的坐标、版本、类型(jar/war)、作用域(compile/runtime/test);
-
核心用途:快速确认项目依赖是否解析成功,是否有缺失依赖;
-
常用命令 :
bash# 基础用法 mvn dependency:resolve # 只列出编译期依赖 mvn dependency:resolve -DincludeScope=compile # 输出详细信息(包括依赖路径) mvn dependency:resolve -Dverbose
4. dependency:analyze(依赖分析)
-
作用:分析项目中「未使用的依赖」「声明但未使用的依赖」「使用但未声明的依赖」;
-
核心用途:清理无用依赖,优化项目体积;
-
常用命令 :
bashmvn dependency:analyze -
输出示例 :
[WARNING] Unused declared dependencies found: [WARNING] org.apache.commons:commons-lang3:jar:3.12.0:compile [WARNING] Used undeclared dependencies found: [WARNING] com.fasterxml.jackson.core:jackson-databind:jar:2.13.4:compileUnused declared dependencies:声明了但代码中未使用的依赖(可删除);Used undeclared dependencies:代码中使用了但未在 POM 中声明(需补充依赖,避免依赖缺失)。
5. dependency:get(下载指定依赖到本地仓库)
-
作用:无需创建项目,直接从中央仓库下载指定依赖到本地 Maven 仓库;
-
核心用途:手动下载缺失的依赖、测试依赖可用性;
-
常用命令 :
bash# 下载指定依赖(groupId:artifactId:version[:type[:classifier]]) mvn dependency:get -Dartifact=org.springframework:spring-core:5.3.20:jar # 下载并输出到指定目录 mvn dependency:get -Dartifact=org.springframework:spring-core:5.3.20:jar -Ddest=./lib
6. dependency:purge-local-repository(清理本地仓库依赖)
-
作用:删除本地仓库中指定依赖的所有版本,强制重新下载;
-
核心用途:解决本地仓库依赖损坏、缓存导致的版本不一致问题;
-
常用命令 :
bash# 清理当前项目的所有依赖 mvn dependency:purge-local-repository # 清理指定依赖 mvn dependency:purge-local-repository -DmanualInclude=org.springframework:spring-core
7. dependency:list(列出所有依赖)
-
作用 :以简洁格式列出项目所有依赖,比
resolve更易读; -
常用命令 :
bash# 基础用法 mvn dependency:list # 只列出运行时依赖 mvn dependency:list -DincludeScope=runtime
四、典型实战场景
场景 1:打包时自动复制依赖到 lib 目录(Java 项目常用)
需求:打包 jar 时,将所有运行时依赖复制到 target/lib,方便通过 java -cp 运行。
xml
<build>
<plugins>
<!-- 编译插件(指定 Java 版本) -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.11.0</version>
<configuration>
<source>8</source>
<target>8</target>
</configuration>
</plugin>
<!-- 复制依赖插件 -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<version>3.6.1</version>
<executions>
<execution>
<id>copy-deps</id>
<phase>package</phase> <!-- 绑定到 package 阶段 -->
<goals>
<goal>copy-dependencies</goal>
</goals>
<configuration>
<outputDirectory>${project.build.directory}/lib</outputDirectory>
<includeScope>runtime</includeScope> <!-- 只复制运行时依赖 -->
<excludeTransitive>false</excludeTransitive> <!-- 包含传递依赖 -->
<overWrite>false</overWrite> <!-- 不重复复制 -->
</configuration>
</execution>
</executions>
</plugin>
<!-- 打包插件(指定主类) -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>3.3.0</version>
<configuration>
<archive>
<manifest>
<mainClass>com.example.App</mainClass>
<addClasspath>true</addClasspath>
<classpathPrefix>lib/</classpathPrefix> <!-- 依赖目录前缀 -->
</manifest>
</archive>
</configuration>
</plugin>
</plugins>
</build>
执行 mvn package 后,target 目录会生成:
my-project-1.0.0.jar(主程序包);lib目录(所有运行时依赖 jar)。
场景 2:排查依赖冲突(找到冲突的 jar 包)
需求:项目启动时报 NoSuchMethodError,怀疑是 commons-lang3 版本冲突。
bash
# 生成依赖树,过滤 commons-lang3
mvn dependency:tree -Dincludes=org.apache.commons:commons-lang3
# 输出示例(显示冲突):
[INFO] com.example:my-project:jar:1.0.0
[INFO] +- org.apache.commons:commons-lang3:jar:3.12.0:compile
[INFO] | \- (org.apache.commons:commons-lang3:jar:3.10.0:compile - omitted for conflict with 3.12.0)
[INFO] \- com.alibaba:fastjson:jar:1.2.83:compile
[INFO] \- org.apache.commons:commons-lang3:jar:3.10.0:compile (omitted for conflict with 3.12.0)
结论:fastjson 依赖的 commons-lang3:3.10.0 被项目直接依赖的 3.12.0 覆盖,可通过 dependencyManagement 统一版本。
场景 3:清理本地仓库损坏的依赖
需求:本地仓库中 spring-core 依赖损坏,导致编译失败。
bash
# 清理 spring-core 依赖并重新下载
mvn dependency:purge-local-repository -DmanualInclude=org.springframework:spring-core -DreResolve=true
-DreResolve=true:清理后自动重新解析并下载依赖。
五、关键配置参数汇总
| 参数名 | 作用 | 默认值 |
|---|---|---|
outputDirectory |
依赖输出目录(如 copy-dependencies 目标) |
target/dependency |
includeScope |
包含的依赖作用域(compile/runtime/test/provided/system) | compile |
excludeScope |
排除的依赖作用域 | 无 |
excludeGroupIds |
排除指定组 ID 的依赖(如 junit,org.mockito) |
无 |
excludeArtifactIds |
排除指定工件 ID 的依赖 | 无 |
excludeTransitive |
是否排除传递依赖 | false |
overWrite |
是否覆盖已存在的依赖文件 | false |
useBaseVersion |
依赖文件名是否使用基础版本(如 3.12.0 而非 3.12.0-SNAPSHOT) | false |
总结
maven-dependency-plugin是 Maven 依赖管理的核心工具,最常用的 Goal 是tree(排查冲突)和copy-dependencies(复制依赖);dependency:tree结合-Dincludes/-Dexcludes可快速定位依赖冲突,是解决 jar 包版本问题的首选;copy-dependencies绑定到package阶段,可自动将依赖复制到指定目录,适配「主 jar + 依赖 lib」的部署方式;dependency:analyze可清理无用依赖,优化项目体积;dependency:get可手动下载指定依赖,无需创建项目;- 配置时建议指定插件版本,并通过
includeScope过滤非必要依赖(如测试依赖),减少输出体积。
spring-boot-maven-plugin
spring-boot-maven-plugin 是 Spring Boot 官方提供的核心 Maven 插件,专门用于构建、打包、运行 Spring Boot 项目 ,是 Spring Boot 项目从「源码」到「可执行产物」的核心工具。它解决了传统 Java 项目打包后需要手动处理依赖、配置主类、启动脚本等问题,实现了「一键打包成可执行 JAR/WAR」的能力。下面从核心定位、核心功能、详细配置、常用 Goal、实战场景、避坑指南 六个维度全面讲解。
简介
- 执行阶段 : package 阶段(当配置为 repackage 目标时)
- 作用 :在打包阶段执行,将普通 JAR 文件重新打包成可执行的 Spring Boot JAR 文件
- 执行顺序 :在 package 阶段中执行,通常在 Maven 自带的打包插件之后
一、核心定位与基础认知
1. 核心作用
- 打包可执行 JAR/WAR:将 Spring Boot 项目(含源码、依赖、配置、启动器)打包为单个可执行 JAR/WAR(「胖包」),无需手动复制依赖;
- 简化运行 :支持直接通过
mvn spring-boot:run启动项目,无需先打包; - 依赖管理:自动处理 Spring Boot 依赖的打包、重定位(避免依赖冲突);
- 定制构建:支持自定义启动类、打包文件名、排除依赖、配置分层构建(优化容器部署)。
2. 基础引入方式
Spring Boot 项目通常通过「父 POM 继承」自动引入插件(推荐),也可手动配置:
xml
<!-- 方式1:继承 Spring Boot 父 POM(自动引入插件,推荐) -->
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.2.4</version> <!-- 对应 Spring Boot 版本,需统一 -->
<relativePath/>
</parent>
<!-- 方式2:手动配置插件(非继承父 POM 时使用) -->
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>3.2.4</version> <!-- 必须与 Spring Boot 版本一致 -->
<executions>
<!-- 绑定 repackage 目标到 package 阶段(核心:打包可执行 JAR) -->
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
<configuration>
<!-- 自定义配置项 -->
<mainClass>com.example.MyApplication</mainClass> <!-- 指定启动类 -->
</configuration>
</plugin>
</plugins>
</build>
二、核心功能与关键配置
1. 核心配置项(<configuration>)
| 配置项 | 作用 | 常用值/示例 | 注意事项 |
|---|---|---|---|
mainClass |
指定 Spring Boot 启动类(全限定名) | com.example.MyApplication |
未配置时,插件会自动扫描含 @SpringBootApplication 的类 |
finalName |
打包后的文件名(默认:artifactId-version) | my-spring-boot-app |
最终产物:target/my-spring-boot-app.jar |
layout |
指定打包布局(控制 JAR/WAR 结构) | JAR/WAR/ZIP/DIR |
Spring Boot 3.x 推荐自动检测,无需手动配置 |
excludeDevtools |
排除 devtools 依赖(生产环境打包时) | true |
devtools 仅用于开发,生产包需排除 |
excludes |
排除指定依赖(避免打包冗余依赖) | 见「实战场景3」 | 格式:groupId:artifactId |
layers |
启用分层构建(优化容器镜像构建) | <enabled>true</enabled> |
Spring Boot 2.3+ 支持,减少镜像构建时间 |
executable |
生成可执行文件(Linux/macOS 可直接 ./app.jar 运行) |
true |
需配合 layout=ZIP(默认已兼容) |
jvmArguments |
运行项目时的 JVM 参数(spring-boot:run 时生效) |
-Xms512m -Xmx1024m |
仅影响插件启动,不影响打包后的 JAR 运行 |
2. 完整配置示例
xml
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>3.2.4</version>
<executions>
<execution>
<id>repackage</id>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
<configuration>
<!-- 核心配置 -->
<mainClass>com.example.MyApplication</mainClass>
<finalName>my-boot-app</finalName>
<!-- 排除开发依赖 -->
<excludeDevtools>true</excludeDevtools>
<!-- 排除指定依赖 -->
<excludes>
<exclude>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
</exclude>
</excludes>
<!-- 启用分层构建 -->
<layers>
<enabled>true</enabled>
</layers>
<!-- 生成可执行 JAR(Linux 可直接运行) -->
<executable>true</executable>
<!-- 运行时 JVM 参数 -->
<jvmArguments>-Xms256m -Xmx512m -Dspring.profiles.active=prod</jvmArguments>
</configuration>
</plugin>
三、常用 Goal(目标)
spring-boot-maven-plugin 的 Goal 是日常开发的核心操作,按使用频率排序如下:
| Goal | 作用 | 常用命令 | 适用场景 |
|---|---|---|---|
spring-boot:repackage |
核心 Goal:将 Maven 普通 JAR 重打包为 Spring Boot 可执行 JAR/WAR(默认绑定到 package 阶段) |
mvn package(自动执行)/ mvn spring-boot:repackage(手动) |
生产打包(必用) |
spring-boot:run |
直接运行 Spring Boot 项目(无需先打包,支持热加载) | mvn spring-boot:run mvn spring-boot:run -Dspring-boot.run.profiles=prod |
开发调试(常用) |
spring-boot:build-image |
构建 Docker 镜像(需本地安装 Docker,Spring Boot 2.3+ 支持) | mvn spring-boot:build-image -Dspring-boot.build-image.imageName=my-app:1.0 |
容器化部署 |
spring-boot:start/stop |
启动/停止 Spring Boot 应用(集成测试时使用) | mvn spring-boot:start / mvn spring-boot:stop |
集成测试(如测试接口可用性) |
spring-boot:help |
查看插件帮助(含参数说明) | mvn spring-boot:help -Ddetail=true |
查阅配置项/Goal 说明 |
关键 Goal 补充说明
-
repackage:
执行mvn package时,Maven 先打包为「普通 JAR」(original-my-boot-app.jar),插件再将其重打包为「可执行 JAR」(my-boot-app.jar),可执行 JAR 包含所有依赖和启动器。 -
run:
支持动态传参,例如指定运行环境、JVM 参数:bash# 指定运行环境 mvn spring-boot:run -Dspring-boot.run.profiles=prod # 指定 JVM 参数 mvn spring-boot:run -Dspring-boot.run.jvmArguments="-Xms512m -Xmx1024m" # 指定启动类(覆盖配置) mvn spring-boot:run -Dspring-boot.run.mainClass=com.example.MyApplication
四、典型实战场景
场景 1:基础打包(生成可执行 JAR)
需求:Spring Boot 3.x 项目,打包为可执行 JAR,指定启动类,排除 devtools。
xml
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>3.2.4</version>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
<configuration>
<mainClass>com.example.BootApplication</mainClass>
<excludeDevtools>true</excludeDevtools>
<finalName>my-boot-app</finalName>
</configuration>
</plugin>
执行 mvn clean package 后,target 目录生成:
original-my-boot-app.jar:Maven 原始普通 JAR;my-boot-app.jar:Spring Boot 可执行 JAR;
运行命令:java -jar target/my-boot-app.jar。
场景 2:开发时快速运行(指定环境)
bash
# 开发环境运行
mvn spring-boot:run -Dspring-boot.run.profiles=dev
# 运行时指定配置文件
mvn spring-boot:run -Dspring-boot.run.arguments="--server.port=8081"
场景 3:排除冗余依赖(减小包体积)
需求:打包时排除 fastjson 和 log4j 依赖(项目未使用)。
xml
<configuration>
<excludes>
<exclude>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
</exclude>
<exclude>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
</exclude>
</excludes>
</configuration>
场景 4:构建 Docker 镜像
需求:将项目打包为 Docker 镜像,指定镜像名和标签。
bash
# 构建镜像(自动命名:groupId/artifactId:version)
mvn spring-boot:build-image
# 自定义镜像名
mvn spring-boot:build-image -Dspring-boot.build-image.imageName=my-boot-app:1.0.0
镜像构建完成后,运行容器:
bash
docker run -p 8080:8080 my-boot-app:1.0.0
场景 5:打包 WAR 包(部署到外部 Tomcat)
Spring Boot 默认打 JAR 包,如需部署到外部 Tomcat,需配置为 WAR 包:
xml
<!-- 1. 修改打包类型为 war -->
<packaging>war</packaging>
<!-- 2. 排除内置 Tomcat(外部容器运行) -->
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<scope>provided</scope>
</dependency>
</dependencies>
<!-- 3. 配置 Spring Boot 插件 -->
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>3.2.4</version>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
<configuration>
<mainClass>com.example.BootApplication</mainClass>
<!-- 兼容外部 Tomcat,无需额外配置 -->
</configuration>
</plugin>
五、常见问题与避坑指南
问题 1:打包后 JAR 无法运行,提示「找不到主类」
-
原因:
- 未指定
mainClass,且插件未扫描到含@SpringBootApplication的类; - 启动类不在源码根目录,或包名配置错误。
- 未指定
-
解决方案:
显式配置mainClass(全限定名),例如:xml<configuration> <mainClass>com.example.MyApplication</mainClass> </configuration>
问题 2:可执行 JAR 体积过大
- 原因:打包了所有依赖(包括测试依赖、冗余依赖);
- 解决方案:
- 排除无用依赖(
<excludes>); - 启用分层构建(
<layers><enabled>true</enabled></layers>); - 使用
spring-boot-jarmode-layertools实现依赖分层,减少镜像构建时间。
- 排除无用依赖(
问题 3:spring-boot:run 启动慢/热加载失效
- 原因:插件默认未启用热加载,或依赖过多;
- 解决方案:
- 引入
spring-boot-devtools依赖(开发环境); - 配置 IDE 自动编译(如 IntelliJ IDEA 开启「Build project automatically」)。
- 引入
问题 4:构建 Docker 镜像失败
- 原因:
- 本地未安装 Docker 或 Docker 未启动;
- 插件版本与 Spring Boot 版本不兼容;
- 解决方案:
- 启动 Docker 服务;
- 确保插件版本与 Spring Boot 版本一致;
- 配置镜像仓库(如阿里云镜像)加速依赖下载。
六、与传统 Maven 插件的区别
| 维度 | spring-boot-maven-plugin | 传统插件(maven-jar-plugin/maven-war-plugin) |
|---|---|---|
| 打包产物 | 可执行胖 JAR/WAR(含所有依赖) | 普通 JAR/WAR(需手动复制依赖) |
| 启动方式 | java -jar app.jar 直接运行 |
java -cp app.jar:lib/* com.example.Main |
| 依赖处理 | 自动打包所有依赖到 JAR 内部 | 需配合 maven-dependency-plugin 复制依赖 |
| 启动类配置 | 自动扫描或简单配置 mainClass |
需手动配置 MANIFEST.MF |
| 容器化支持 | 内置 build-image 生成 Docker 镜像 |
需手动编写 Dockerfile |
总结
- 核心价值 :
spring-boot-maven-plugin是 Spring Boot 项目打包/运行的核心,实现了「一键生成可执行胖包」,无需手动处理依赖和启动配置; - 核心 Goal :
repackage(打包)和run(运行)是日常开发最常用的两个目标,build-image适合容器化部署; - 必配项:继承 Spring Boot 父 POM 可自动引入插件,手动配置时需保证插件版本与 Spring Boot 版本一致;
- 避坑重点:打包失败优先检查「启动类配置」「依赖冲突」「Spring Boot 版本与插件版本一致性」;
- 优化建议 :生产打包排除 devtools 等开发依赖,启用分层构建减小镜像体积,容器化部署使用
build-image简化流程。