spring-boot-maven-plugin 将spring打包成单个jar的工作原理
spring-boot-maven-plugin 是 Spring Boot 的 Maven 插件,它的核心功能是将 Spring Boot 项目打包成一个独立的、可执行的 Fat JAR(包含所有依赖的 JAR 包)。以下是它的工作原理详解:
1. 默认 Maven 打包 vs Spring Boot 插件打包
-  
标准 Maven 打包:
默认的maven-jar-plugin会生成一个普通的 JAR 包,仅包含项目的编译类文件(target/classes)和资源文件,不包含依赖库。 -  
Spring Boot 插件打包:
spring-boot-maven-plugin会生成一个 Fat JAR,将项目的代码、资源文件以及所有依赖的第三方库(BOOT-INF/lib)和启动类加载器(org.springframework.boot.loader)打包到同一个 JAR 中,使其可以直接通过java -jar运行。 
2. Fat JAR 的核心结构
生成的 Fat JAR 包含以下关键目录和文件:
your-app.jar
 ├── BOOT-INF
 │ ├── classes # 项目的编译类文件(对应 src/main/java 和 src/main/resources)
 │ └── lib # 所有依赖的第三方 JAR 文件
 ├── META-INF
 │ ├── MANIFEST.MF # JAR 包的元数据(指定启动类、类路径等)
 │ └── maven # Maven 构建信息
 └── org
 └── springframework
 ┣── boot
 ┗── loader # Spring Boot 的类加载器(JarLauncher)
3. 核心工作原理
3.1 依赖嵌入
- 插件通过 
Maven Shade Plugin的变体,将所有依赖的 JAR 文件解压并合并到BOOT-INF/lib目录中。 - 依赖库的路径会被记录在 
MANIFEST.MF的Class-Path属性中。 
3.2 启动类加载器
-  
Spring Boot 使用自定义的类加载器
org.springframework.boot.loader.Launcher(如JarLauncher)来启动应用。 -  
MANIFEST.MF中的关键属性:Main-Class: org.springframework.boot.loader.JarLauncher # 启动入口
Start-Class: com.example.YourApplication # 用户定义的 Spring Boot 主类 
3.3 启动流程
- 执行 
java -jar your-app.jar时,JVM 根据MANIFEST.MF找到JarLauncher。 JarLauncher负责:- 加载 
BOOT-INF/lib中的依赖库。 - 找到 
Start-Class(即用户定义的@SpringBootApplication主类)。 - 调用 
SpringApplication.run()启动 Spring Boot 应用。 
- 加载 
 
4. 插件配置示例(pom.xml)
 org.springframework.boot spring-boot-maven-plugin com.example.YourApplication true org.unwanted unwanted-lib repackage 5. 关键 Maven 生命周期阶段
package阶段:
Maven 默认会先调用maven-jar-plugin生成普通 JAR(如your-app-0.0.1.jar)。repackage目标:
spring-boot-maven-plugin的repackage目标会在此基础上,将普通 JAR 和依赖重新打包为 Fat JAR(如your-app-0.0.1.jar,覆盖原文件)。
6. 高级特性
6.1 分层打包(Layered JAR)
- 目的:优化 Docker 镜像构建(利用分层缓存)。
 - 结构: 
dependencies:第三方依赖。spring-boot-loader:Spring Boot 类加载器。snapshot-dependencies:快照依赖。application:应用代码和资源。
 
6.2 排除依赖
通过 <excludes> 配置移除不需要的依赖,减少 JAR 包体积。
7. 总结
- 核心功能:将 Spring Boot 应用及其依赖打包成一个自包含的 JAR。
 - 关键机制:自定义类加载器(
JarLauncher)和嵌套依赖结构(BOOT-INF/lib)。 - 优势:简化部署,无需外部 Web 服务器或依赖管理。
 - 适用场景:独立运行、容器化部署(Docker)等。
 
