SpringBoot打包的jar包与普通的jar包有什么区别 - Sanarous的博客
🔆
✍️
🌞

SpringBoot打包的jar包与普通的jar包有什么区别

有些人可能会将 SpringBoot 打包成的 jar 包作为项目依赖导入到其它项目中,结果启动就会发现会报找不到类的错误。会有这种操作的误区,是因为混淆了 SpringBoot 打包成的 jar 包与普通的 jar 包。

SpringBoot 中打包的插件

我们常把 SpringBoot 打包成的 jar 包称为可执行 jar 包,而普通 jar 包往往作为依赖使用,这并不是说普通 jar 包不能执行,如果普通 jar 包中确定了 Main 入口主类,也是可以直接通过 java -jar xxx.jar方式运行的。它们之间的主要区别在于 SpringBoot 中有一个默认打包插件 Spring-boot-maven-plugin,这个插件有 5 个方面的功能,从插件配置就可以看出来:

五个功能分别是:

  • build-info:生成项目的构建信息文件 build-info.properties
  • repackage:这个是默认 goal,在 mvnpackage 执行之后,这个命令再次打包生成可执行的 jar,同时将 mvnpackage 生成的 jar 重命名为 *.origin
  • run:这个可以用来运行 Spring Boot 应用
  • start:这个在 mvn integration-test 阶段,进行 SpringBoot 应用生命周期的管理
  • stop:这个在 mvn integration-test 阶段,进行 SpringBoot 应用生命周期的管理

默认情况下使用就是 repackage 功能,其他功能要使用,则需要开发者显式配置。

repackage

repackage 功能的 作用,就是在打包的时候,多做一点额外的事情:

  1. 首先使用命令 mvnpackage 对项目打包时,打包成的 jar 就是一个普通的 jar 包,可以被其它项目依赖
  2. repackage 打包命令就是对上面打成的 jar 包再次打包,将之打成 SpringBoot 可执行的 jar 包,通过将第一步打成的 jar 重命名为 *.original 文件

举个例子,我们对任意一个 SpringBoot 项目进行打包,可以执行 mvnpackage 命令,也可以直接在 IDEA 中点击 package,如下所示:

打包成功后,target 中的文件如下:

其中有两个 jar 包,一个叫做 tumo-0.01-SNAPHOT.jar 这是最终被打包成的可执行 jar 包,第二个就是 tumo-0.01-SNAPHOT.jar.original 则是在打包过程中,被重命名的 jar,通过对这两个文件的解压,我们可以看出这两者之间的差异。

两个 jar 的比较

最终的可执行 jar 解压之后,目录如下:

可以看到,可执行 jar 中,我们自己的代码是存在 于 BOOT-INF/classes/ 目录下,另外,还有一个 META-INF 的目录,该目录下有一个 MANIFEST.MF 文件,打开该文件,内容如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
Manifest-Version: 1.0
Implementation-Title: tumo
Implementation-Version: 0.0.1-SNAPSHOT
Built-By: zuoxiang
Implementation-Vendor-Id: cn.bestzuo
Spring-Boot-Version: 2.1.3.RELEASE
Main-Class: org.springframework.boot.loader.JarLauncher
Start-Class: cn.bestzuo.TumoBlogApplication
Spring-Boot-Classes: BOOT-INF/classes/
Spring-Boot-Lib: BOOT-INF/lib/
Created-By: Apache Maven 3.6.0
Build-Jdk: 1.8.0_211
Implementation-URL: https://projects.spring.io/spring-boot/#/spring-bo
ot-starter-parent/tumo

可以看到,这里定义了一个 Start-Class,这就是可执行 jar 的入口类, Spring-Boot-Classes 表示我们自己代码编译后的位置, Spring-Boot-Lib 则表示项目依赖的 jar 的位置。

换句话说,如果自己要打一个可执行 jar 包的话,除了添加相关依赖之外,还需要配置 META-INF/MANIFEST.MF 文件。

那么原始的普通 jar 包呢?我们解压一下看一下:

解压后可以看到,根目录就相当于我们的 classpath,解压之后,直接就能看到我们的代码,它也有 META-INF/MANIFEST.MF 文件,但是文件中没有定义启动类等。

1
2
3
4
5
6
7
8
9
Manifest-Version: 1.0
Implementation-Title: tumo
Implementation-Version: 0.0.1-SNAPSHOT
Built-By: zuoxiang
Implementation-Vendor-Id: cn.bestzuo
Created-By: Apache Maven 3.6.0
Build-Jdk: 1.8.0_211
Implementation-URL: https://projects.spring.io/spring-boot/#/spring-bo
ot-starter-parent/tumo

这个 jar 也没有将项目的依赖打包进来。

从这里我们就可以看出,两个 jar ,虽然都是 jar 包,但是内部结构是完全不同的,因此一个可以直接执行,另一个则可以被其他项目依赖。

如果这篇文章对您很有帮助,不妨
-------------    本文结束  感谢您的阅读    -------------
0%