Maven - Spring Boot 项目打包本地 jar 的 3 种方法

文章目录


Pre

Maven - Manual Maven JAR Installation:用 mvn install:install-file 安装本地 JAR 的实用指南

概述

在 Spring Boot 项目中,通常依赖包会从 Maven 中央仓库或私有仓库获取,并由 spring-boot-maven-plugin 自动打包进最终的可执行 fat jar(BOOT-INF/lib 目录)。

但在实际开发中,有时会遇到无法从公共或私有仓库获取的第三方 jar,例如厂商提供的 SDK、本地编译生成的工具包、未开源的内部依赖等。

如果直接使用 <scope>system</scope> 引入本地 jar,虽然能在编译时解析,但 Maven 默认不会将 system scope 依赖打入 Spring Boot 的 fat jar 中,导致部署后运行时找不到该类。

为了解决这一问题,需要在打包阶段显式将这些 jar 文件复制到 BOOT-INF/lib 目录,确保它们随 Spring Boot 应用一起分发与运行。

这个场景尤其适用于:

  • 快速集成:临时引入无法上传至私服的第三方 jar。
  • 离线部署:运行环境无法访问外部仓库。
  • 封闭式交付:需要将全部依赖打包成一个独立可运行的 jar 文件。

方案思路

  1. 编译期 :使用 <scope>system</scope> 让本地 jar 参与编译。
  2. 打包期 :通过 maven-resources-pluginprocess-resources 阶段将本地 jar 文件复制到 target/classes/BOOT-INF/lib,这样 spring-boot-maven-pluginrepackage 时会将其一并打入 fat jar。
  3. 运行期 :由于 jar 已进入 BOOT-INF/lib,Spring Boot 的类加载器会自动加载。

构建流程图

本地 jar 放到 src/main/resources/lib 执行 mvn package maven-resources-plugin 在 process-resources 阶段执行 复制 *.jar 到 target/classes/BOOT-INF/lib Spring Boot repackage 阶段启动 收集 BOOT-INF/lib 内的 jar 生成可执行 fat jar 部署并运行 Spring Boot 类加载器加载 BOOT-INF/lib 中的 jar

工作机制说明

  1. 资源复制阶段
    maven-resources-pluginprocess-resources 阶段,将 src/main/resources/lib 中的所有 jar 文件复制到 target/classes/BOOT-INF/lib
  2. 打包阶段
    spring-boot-maven-pluginrepackage 阶段会打包所有在 BOOT-INF/lib 的 jar 到最终可执行 jar 中。
  3. 运行阶段
    Spring Boot 启动时会用自带的类加载器加载 BOOT-INF/lib 中的所有 jar,使它们在运行时可用。

目录结构示例

java 复制代码
my-project/
├── src/
│   ├── main/
│   │   ├── java/...         # 源码
│   │   ├── resources/
│   │   │   ├── application.yml
│   │   │   └── lib/
│   │   │       └── your.jar  # 本地 jar
├── pom.xml

POM 配置模板

xml 复制代码
<dependency>
    <groupId>com.xxx</groupId>
    <artifactId>your-artifact</artifactId>
    <version>1.0.0</version>
    <scope>system</scope>
    <systemPath>${project.basedir}/src/main/resources/lib/your.jar</systemPath>
</dependency>

<build>
    <plugins>
        <!-- 复制本地 jar 到 BOOT-INF/lib -->
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-resources-plugin</artifactId>
            <version>3.3.0</version>
            <executions>
                <execution>
                    <id>copy-system-jars</id>
                    <phase>process-resources</phase>
                    <goals>
                        <goal>copy-resources</goal>
                    </goals>
                    <configuration>
                        <outputDirectory>${project.build.outputDirectory}/BOOT-INF/lib</outputDirectory>
                        <resources>
                            <resource>
                                <directory>${project.basedir}/src/main/resources/lib</directory>
                                <includes>
                                    <include>*.jar</include>
                                </includes>
                            </resource>
                        </resources>
                    </configuration>
                </execution>
            </executions>
        </plugin>

        <!-- Spring Boot 打包插件 -->
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
            <configuration>
                <includeSystemScope>true</includeSystemScope>
            </configuration>
        </plugin>
    </plugins>
</build>

构建与验证

bash 复制代码
mvn clean package

验证 jar 是否被打入:

bash 复制代码
jar tf target/my-project-0.0.1-SNAPSHOT.jar | grep BOOT-INF/lib

应能看到 your.jar 记录。


注意事项

  • system scope 在 Maven 官方中不推荐长期使用,不具备依赖冲突检测功能,适合临时方案。

  • 如果 jar 需要长期维护,建议安装到本地仓库:

    bash 复制代码
    mvn install:install-file \
      -Dfile=src/main/resources/lib/your.jar \
      -DgroupId=com.xxx \
      -DartifactId=your-artifact \
      -Dversion=1.0.0 \
      -Dpackaging=jar
  • 团队协作建议使用私服(Nexus / Artifactory)管理。


方案优缺点

方法 核心做法 是否自动打包进 fat jar 优点 缺点 适用场景
方法 1:安装到本地 Maven 仓库 mvn install:install-file 安装到 ~/.m2/repository,pom.xml 正常依赖 ✅ 会打包 - 符合 Maven 规范 - 支持版本管理与冲突检测 - CI/CD 无障碍 - 初次使用需执行安装命令 - jar 更新需重新安装 jar 可长期使用,且团队或构建环境可访问本地/远程仓库
方法 2:上传到私服(Nexus/Artifactory) 上传 jar 到私服仓库,pom.xml 正常依赖 ✅ 会打包 - 团队共享方便 - 支持版本管理与依赖分析 - CI/CD 最友好 - 需要搭建和维护私服 - 上传步骤比本地仓库多 多人协作项目,需稳定依赖和自动化构建
方法 3:直接内嵌 jar(system scope) 把 jar 放到 src/main/resources/lib<scope>system</scope> ❌ 默认不会打包(可用 includeSystemScope=true 或 maven-resources-plugin 手动复制) - 无需上传仓库 - 依赖文件随项目走 - 不走 Maven 依赖管理 - 无版本冲突检测 - CI/CD 需额外处理 - jar 升级需手动替换 临时测试或快速 PoC,构建环境固定且可直接带 jar

方法 是否打包进 fat jar 优点 缺点 适用场景
本方案(system + 手动复制) 快速接入,适合临时调试或离线部署 维护成本高,不做依赖冲突检测 临时/封闭环境
本地 Maven 仓库安装 符合 Maven 规范,支持版本管理 jar 更新需重新安装 长期使用,本地构建
上传私服 团队共享方便,CI/CD 友好 需搭建和维护私服 多人协作,长期依赖

相关推荐
叶 落11 分钟前
[Maven 基础课程]10_Maven 私服
maven·maven 入门·maven 基础课程·maven 基础
城管不管1 小时前
Java EE、Java SE 和 Spring Boot
java·spring boot·java-ee
菜鸟小九2 小时前
SSM(MybatisPlus)
java·开发语言·spring boot·后端
不爱编程的小九九2 小时前
小九源码-springboot051-智能推荐旅游平台
java·spring boot·后端
老华带你飞2 小时前
小区服务|基于Java+vue的小区服务管理系统(源码+数据库+文档)
java·数据库·vue.js·spring boot·论文·毕设·小区服务管理系统
龙茶清欢2 小时前
具有实际开发参考意义的 MyBatis-Plus BaseEntity 基类示例
java·spring boot·spring cloud·mybatis
计算机学姐2 小时前
基于微信小程序的扶贫助农系统【2026最新】
java·vue.js·spring boot·mysql·微信小程序·小程序·mybatis
C++chaofan3 小时前
游标查询在对话历史场景下的独特优势
java·前端·javascript·数据库·spring boot
小蒜学长3 小时前
springboot房地产销售管理系统的设计与实现(代码+数据库+LW)
java·数据库·spring boot·后端
齐 飞3 小时前
Spring Cloud Alibaba快速入门-Sentinel熔断规则
spring boot·spring cloud·sentinel