Spring/SpringBoot系列之SpringBoot打jar包可执行不可被依赖【十四】

Spring Boot 应用默认打成的 jar 包 叫做 可执行 jar,这种 jar 不同于普通的 jar,普通的 jar 不可以通过 java -jar xxx.jar 命令执行,普通的 jar 主要是被其他应用依赖。相反可执行jar 不可以被其他的应用所依赖,即使强制依赖,也无法获取里边的类。但是可执行 jar 并不是 Spring Boot 独有的,Java 工程本身就可以打包成可执行 jar 。

同样是执行 mvn package 命令进行项目打包,Spring Boot 项目就打成了可执行 jar ,而普通项目则打包成了不可执行 jar。主要是因为Spring Boot 项目中一个默认的插件配置 spring-boot-maven-plugin:
Spring/SpringBoot系列之SpringBoot打jar包可执行不可被依赖【十四】_第1张图片
这个打包插件有 5 个功能:

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

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

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

  • 首先 mvn package 命令 对项目进行打包,打成一个 普通的 jar
  • repackage 命令,对第一步 打包成的 jar 进行再次打包,将之打成一个 可执行 jar ,然后将第一步打成的 jar 重命名为 *.original 文件

对任意一个 Spring Boot 项目进行打包,可以执行 mvn package 命令,也可以直接在 IDEA 中点击 package ,如下 :
Spring/SpringBoot系列之SpringBoot打jar包可执行不可被依赖【十四】_第2张图片
打包成功之后, target 下的文件如下:
Spring/SpringBoot系列之SpringBoot打jar包可执行不可被依赖【十四】_第3张图片
这里有两个文件,第一个 demo-0.0.1-SNAPSHOT.jar 表示打包成的可执行 jar ,第二个 demo-0.0.1-SNAPSHOT.jar.original 则是在打包过程中 ,被重命名的 jar。通过对这两个文件的解压,可以看出这两者之间的差异。

demo-0.0.1-SNAPSHOT.jar:
Spring/SpringBoot系列之SpringBoot打jar包可执行不可被依赖【十四】_第4张图片
可以看到,可执行 jar 中,我们自己的代码是存在 于 BOOT-INF/classes/ 目录下,另外,还有一个 META-INF 的目录,该目录下有一个 MANIFEST.MF 文件,打开该文件,内容如下:
Spring/SpringBoot系列之SpringBoot打jar包可执行不可被依赖【十四】_第5张图片
这里定义了一个 Start-Class,这就是可执行 jar 的入口类,Spring-Boot-Classes 表示我们自己的代码编译后的位置,Spring-Boot-Lib 则表示项目依赖的 jar 的位置。

将不可执行jar的后缀 .original 除去,然后给文件重命名,重命名完成,进行解压:
Spring/SpringBoot系列之SpringBoot打jar包可执行不可被依赖【十四】_第6张图片
解压后可以看到,不可执行 jar 根目录就相当于我们的 classpath,解压之后,直接就能看到我们的代码,它也有 META-INF/MANIFEST.MF 文件,但是文件中没有定义启动类等:
Spring/SpringBoot系列之SpringBoot打jar包可执行不可被依赖【十四】_第7张图片
注意:这个不可以执行 jar 也没有将项目的依赖打包进来。

从这里我们就可以看出,两个 jar ,虽然都是 jar 包,但是内部结构是完全不同的。

一般来说,Spring Boot 直接打包成可执行 jar 就可以,不建议将 Spring Boot 作为普通的 jar 被其他的项目所依赖。如果有这种需求,建议将被依赖的部分,单独抽出来做一个普通的 Maven 项目,然后引用这个 Maven 项目。

如果非要将 Spring Boot 打包成一个普通 jar 被其他项目依赖,技术上来说,也是可以的,给 spring-boot-maven-plugin 插件添加如下配置:

<build>
    <plugins>
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
            <configuration>
                <classifier>exec</classifier>
            </configuration>
        </plugin>
    </plugins>
</build>

配置的 classifier 表示可执行 jar 的名字,配置了这个之后,在插件执行 repackage 命令时,就不会给 mvn package 所打成的 jar 重命名了,打包后的 jar 如下:
在这里插入图片描述
第一个 jar 表示可以被其他项目依赖的 jar ,第二个 jar 则表示一个可执行 jar。

你可能感兴趣的:(java,java,maven,spring,boot)