14. Spring Boot 打成的 jar 和普通的 jar 有什么区别
大约 4 分钟
Spring Boot 打包的 JAR 文件与普通的 JAR 文件有一些显著的区别,主要体现在运行方式、结构和内置功能上。以下是它们的主要区别:
1. 运行方式
- 普通 JAR 文件:
- 普通的 JAR 文件通常只是一个包含
.class
文件和其他资源文件的压缩包,使用java -jar
命令运行时,JVM 会加载这个 JAR 文件中的类,并运行指定的main
方法。 - 普通的 JAR 文件一般依赖于外部的类路径(classpath),在运行时需要通过
-cp
或者-classpath
参数指定所有依赖的 JAR 文件位置。
- 普通的 JAR 文件通常只是一个包含
- Spring Boot 打包的 JAR 文件:
- Spring Boot 的 JAR 文件是一个可执行的 JAR 文件,包含了所有项目依赖的库文件,以及 Spring Boot 的启动器。
- 使用
java -jar
命令运行时,Spring Boot 自带的类加载器Launcher
会处理依赖加载,并启动 Spring Boot 应用,类似于一个独立的应用程序。 - 这种 JAR 文件被称为 "fat JAR" 或 "über JAR",因为它打包了所有依赖。
2. 结构
- 普通 JAR 文件:
- 普通 JAR 文件的结构相对简单,通常包含项目的
.class
文件和META-INF
目录。META-INF
目录下可能会有一个MANIFEST.MF
文件,定义了入口点(Main-Class
)和其他元数据。 - 普通 JAR 文件的依赖库不会被打包到同一个 JAR 文件中,需要通过类路径来引用。
- 普通 JAR 文件的结构相对简单,通常包含项目的
- Spring Boot JAR 文件:
- Spring Boot 的 JAR 文件结构更加复杂,包含多个目录和文件:
BOOT-INF/classes/
:包含项目的编译输出(即.class
文件)。BOOT-INF/lib/
:包含项目所有依赖的 JAR 文件。META-INF/
:包含应用的元数据和MANIFEST.MF
文件。org/springframework/boot/loader/
:包含 Spring Boot 的启动类,如Launcher
、JarLauncher
、WarLauncher
等。
- 这种结构允许 Spring Boot 在一个 JAR 文件中包含所有依赖,并通过自定义类加载器来加载这些依赖。
- Spring Boot 的 JAR 文件结构更加复杂,包含多个目录和文件:
3. 内置服务器
- 普通 JAR 文件:
- 普通 JAR 文件一般不会包含任何内嵌服务器(如 Tomcat、Jetty 等)。对于 Web 应用,通常需要将项目打包为 WAR 文件,并部署到外部的 Web 服务器或应用服务器中(如 Tomcat、JBoss 等)。
- Spring Boot JAR 文件:
- Spring Boot JAR 文件通常包含一个内嵌的 Web 服务器(如 Tomcat、Jetty、Undertow),这使得 Spring Boot 应用可以直接以 JAR 文件的形式运行,而不需要外部的 Web 服务器。
- 这种方式简化了部署流程,尤其适合微服务架构中的独立服务。
4. 部署与分发
- 普通 JAR 文件:
- 普通 JAR 文件一般需要与其他依赖库一起分发或者在运行时指定类路径。因此,在部署时需要考虑如何将所有依赖打包和分发。
- 部署到服务器上时,通常需要额外的脚本或配置来指定类路径。
- Spring Boot JAR 文件:
- Spring Boot JAR 文件可以独立运行,部署时只需要一个文件。你只需要将这个 JAR 文件上传到服务器,然后通过
java -jar
命令运行即可。 - 这种打包方式适合 DevOps 流程,简化了应用的分发和部署。
- Spring Boot JAR 文件可以独立运行,部署时只需要一个文件。你只需要将这个 JAR 文件上传到服务器,然后通过
5. 启动速度
- 普通 JAR 文件:
- 普通 JAR 文件启动速度通常较快,因为它们依赖的库已经由类路径加载,且没有复杂的启动过程。
- Spring Boot JAR 文件:
- Spring Boot JAR 文件在启动时需要解压或扫描
BOOT-INF/lib/
目录下的所有依赖,并通过自定义类加载器加载依赖库,因此启动速度可能略慢。 - 然而,Spring Boot 提供了各种优化手段,比如
spring-boot-devtools
的自动重启功能和spring-boot-maven-plugin
的打包优化参数,来提升启动性能。
- Spring Boot JAR 文件在启动时需要解压或扫描
6. 开发体验
- 普通 JAR 文件:
- 开发时,普通 JAR 文件通常与传统的 Spring 项目开发体验一致,需要在 IDE 中配置类路径并手动管理依赖库。
- Spring Boot JAR 文件:
- Spring Boot 提供了更好的开发体验,通过起步依赖(Starters)简化了依赖管理,并且内置的开发者工具(如 DevTools)能够加速开发过程和应用调试。
- 由于内嵌服务器和自动配置的特性,开发者可以快速启动一个完整的应用而不需要复杂的环境配置。
总结
- Spring Boot JAR 文件 是一个 "fat JAR",包含了所有依赖库和内嵌的服务器,能够独立运行,适合现代的微服务架构和 DevOps 部署流程。
- 普通 JAR 文件 是传统的打包方式,通常需要依赖外部的类路径和服务器,不包含内嵌的运行环境,适合分布式的开发环境和传统的企业应用部署。
通过 Spring Boot 提供的打包机制,开发者可以更轻松地管理和部署 Java 应用,减少依赖冲突和部署复杂性。