maven 插件

构建过程中的执行顺序

  1. maven-compiler-plugin :编译源代码(compile阶段)所有插件:「前置基础」
  2. maven-jar-plugin/maven-war-plugin :打包编译后的class文件(package阶段)生成通 JAR/WAR
  3. maven-dependency-plugin :复制依赖项(package阶段)仅解决「依赖分析/分离」的辅助问题
  4. 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 运行;
  • 关键细节
    1. spring-boot-maven-plugin 不会「重复打包」,而是基于 maven-jar-plugin 的产物做「重打包(repackage)」
    2. 即使你不显式配置 maven-jar-plugin,Spring Boot 父 POM 也会默认引入(版本与 Spring Boot 适配),保证基础打包流程;
    3. 两者无冲突: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 ↔ 其他插件:「可选辅助,无冲突」
  • 核心定位 :它是「依赖管理工具」,不参与核心打包,而是按需补充功能
  • 与其他插件的配合场景
    1. maven-jar-plugin 配合:传统 Java 项目打普通 JAR 后,用它复制依赖到 lib 目录(实现「主 JAR + 外部依赖」分离打包);
    2. spring-boot-maven-plugin 配合:非必需(Spring Boot 可执行 JAR 已内置依赖),仅在「分离依赖」场景下使用(如想把依赖放到外部目录,减小 JAR 体积);
    3. 通用场景:无论哪种打包方式,都可用它分析依赖冲突(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);
  • 构建流程:
    1. 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
  • 构建流程:
    1. 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 特性);
  • 构建流程:
    1. 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-pluginrepackage 目标,是把这个标准 JAR 重新打包为「Spring Boot 可执行 JAR」(内置依赖、启动器);
  • 即使你不写 maven-jar-plugin 配置,Spring Boot 父 POM 也会自动引入它(版本适配),保证基础打包。
误解 2:maven-dependency-plugin 与 spring-boot-maven-plugin 重复(都处理依赖)?

❌ 处理方式完全不同:

  • spring-boot-maven-plugin:将依赖内置到可执行 JAR/WARBOOT-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)。

总结

  1. 无重复,是「分工协作」:5 个插件覆盖「编译 → 基础打包 → 增强打包 → 依赖管理」全流程,每个插件聚焦单一职责;
  2. 核心依赖链compilerjar/warspring-boot-plugin 是 Spring Boot 项目的核心链路,dependency-plugin 是按需使用的辅助工具;
  3. 关键边界
    • 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
  • 解决方案:
    1. 确认本地 JDK 版本 ≥ 配置的版本;
    2. 配置 MAVEN_OPTS 指定 JDK 路径,或在 IDE 中指定 Maven 运行的 JDK。
问题 4:编译大项目报 OutOfMemoryError
  • 原因:编译进程内存不足;
  • 解决方案:开启 fork=true,并增大 meminitial/maxmem

总结

  1. 核心价值maven-compiler-plugin 是 Java 项目编译的基础,最关键的配置是「Java 版本」和「编码」,必须显式配置以避免兼容问题;
  2. 版本配置 :Java 8 用 source + target,Java 9+ 推荐用 release 简化配置;
  3. 必配项encoding=UTF-8 + fork=true 是所有项目的基础配置,可解决编码和类加载冲突问题;
  4. 避坑重点:编译报错优先检查 Java 版本、编码、JDK 运行环境三者是否一致;
  5. 优化配置 :大项目需调整编译内存(meminitial/maxmem),测试场景可跳过测试源码编译(testSkip=true)。

maven-jar-pluginmaven-war-plugin

maven-jar-pluginmaven-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 目录中
      • 支持排除特定依赖项
  • 执行阶段 : 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(主类、依赖路径) webXmlfailOnMissingWebXmlpackagingExcludes
运行方式 java -jar 直接运行 部署到 Servlet 容器(Tomcat/Jetty)运行

总结

  1. maven-jar-plugin
    • 核心是打包 JAR 包,重点配置 manifest 指定主类实现可执行 JAR;
    • 配合 maven-dependency-plugin 复制依赖到 lib 目录,是 Java 项目打包的基础;
  2. maven-war-plugin
    • 核心是打包 WAR 包,适配 Web 项目,重点配置 webXmlfailOnMissingWebXml
    • Spring Boot 打 WAR 包需排除内置 Tomcat,设置 failOnMissingWebXml=false
  3. 两者均默认绑定到 package 阶段,执行 mvn package 即可自动打包,无需手动执行 Goal;
  4. 自定义打包文件名用 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>
  • 常用命令(手动执行)

    bash 复制代码
    mvn 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(依赖分析)
  • 作用:分析项目中「未使用的依赖」「声明但未使用的依赖」「使用但未声明的依赖」;

  • 核心用途:清理无用依赖,优化项目体积;

  • 常用命令

    bash 复制代码
    mvn 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:compile
    • Unused 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

总结

  1. maven-dependency-plugin 是 Maven 依赖管理的核心工具,最常用的 Goal 是 tree(排查冲突)和 copy-dependencies(复制依赖);
  2. dependency:tree 结合 -Dincludes/-Dexcludes 可快速定位依赖冲突,是解决 jar 包版本问题的首选;
  3. copy-dependencies 绑定到 package 阶段,可自动将依赖复制到指定目录,适配「主 jar + 依赖 lib」的部署方式;
  4. dependency:analyze 可清理无用依赖,优化项目体积;dependency:get 可手动下载指定依赖,无需创建项目;
  5. 配置时建议指定插件版本,并通过 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:排除冗余依赖(减小包体积)

需求:打包时排除 fastjsonlog4j 依赖(项目未使用)。

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 无法运行,提示「找不到主类」
  • 原因:

    1. 未指定 mainClass,且插件未扫描到含 @SpringBootApplication 的类;
    2. 启动类不在源码根目录,或包名配置错误。
  • 解决方案:
    显式配置 mainClass(全限定名),例如:

    xml 复制代码
    <configuration>
      <mainClass>com.example.MyApplication</mainClass>
    </configuration>
问题 2:可执行 JAR 体积过大
  • 原因:打包了所有依赖(包括测试依赖、冗余依赖);
  • 解决方案:
    1. 排除无用依赖(<excludes>);
    2. 启用分层构建(<layers><enabled>true</enabled></layers>);
    3. 使用 spring-boot-jarmode-layertools 实现依赖分层,减少镜像构建时间。
问题 3:spring-boot:run 启动慢/热加载失效
  • 原因:插件默认未启用热加载,或依赖过多;
  • 解决方案:
    1. 引入 spring-boot-devtools 依赖(开发环境);
    2. 配置 IDE 自动编译(如 IntelliJ IDEA 开启「Build project automatically」)。
问题 4:构建 Docker 镜像失败
  • 原因:
    1. 本地未安装 Docker 或 Docker 未启动;
    2. 插件版本与 Spring Boot 版本不兼容;
  • 解决方案:
    1. 启动 Docker 服务;
    2. 确保插件版本与 Spring Boot 版本一致;
    3. 配置镜像仓库(如阿里云镜像)加速依赖下载。

六、与传统 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

总结

  1. 核心价值spring-boot-maven-plugin 是 Spring Boot 项目打包/运行的核心,实现了「一键生成可执行胖包」,无需手动处理依赖和启动配置;
  2. 核心 Goalrepackage(打包)和 run(运行)是日常开发最常用的两个目标,build-image 适合容器化部署;
  3. 必配项:继承 Spring Boot 父 POM 可自动引入插件,手动配置时需保证插件版本与 Spring Boot 版本一致;
  4. 避坑重点:打包失败优先检查「启动类配置」「依赖冲突」「Spring Boot 版本与插件版本一致性」;
  5. 优化建议 :生产打包排除 devtools 等开发依赖,启用分层构建减小镜像体积,容器化部署使用 build-image 简化流程。
相关推荐
weixin_704266052 小时前
SpringMVC基础了解
java·spring·mvc
BUG?不,是彩蛋!2 小时前
AI智慧社区--从0到1开发柱状图数据接口
java·spring boot·后端·intellij-idea·mybatis
arvin_xiaoting2 小时前
OpenClaw Agent与Sub-agent架构深度分析:关系、通信与权限隔离
java·linux·架构·多智能体·ai agent·openclaw·sub-agent
码农时代者2 小时前
拒绝重复造轮子!开发者如何靠“高质量源码”实现项目高效交付?
java·python·php
稽稽稽稽不如人2 小时前
《从零开始的java从入门到入土的学习生活——JavaWeb后端篇》Chapter18——JavaWeb后端篇学习记录——AOP 面向切面编程
java·学习·生活
BUG?不,是彩蛋!2 小时前
从零到一掌握 K 线与技术指标:Java 实战教程 | MA, RSI, MACD 全解析
java·开发语言·spring boot·量化投资
qq_427940342 小时前
java-UI自动化selenium+TestNG
java·selenium·自动化
biter down2 小时前
C++ 设计不可被继承的类
java·开发语言·c++
于先生吖2 小时前
Java 智慧社区本地生活系统:上门服务 + 商城模块完整开发
java·大数据·生活