2024-12-16  阅读(6)
版权声明:本文为博主付费文章,严禁任何形式的转载和摘抄,维权必究。 本文链接:https://www.skjava.com/mianshi/baodian/detail/2010016437

回答

Spring Boot 的 jar 之所以可以直接运行,主要是因为它是一个可执行的 Jar(Fat Jar),并且内部集成了一个嵌入式的 Servlet 容器(比如 Tomcat、Jetty 或 Undertow)。这种方式可以直接通过 java -jar 命令运行,而无需单独部署到外部应用服务器中。这种运行机制的核心在于 Spring Boot 使用了一个特殊的启动类 org.springframework.boot.loader.JarLauncher,以及自定义的类加载机制。

简单点说就是:

  • Spring Boot 将所有的依赖和资源打包到一个单独的 Jar 文件中。
  • 使用 JarLauncher 类管理启动流程,内部就是通过反射机制执行我们的 main()
  • 提供嵌入式容器,让应用直接运行。

详解

可执行的 jar

Spring Boot 提供了一个名叫 spring-boot-maven-plugin 的 maven 项目打包插件,如下:

<plugin>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-maven-plugin</artifactId>
</plugin>

通过这个插件,我们可以非常方便地将 Spring Boot 项目打包成一个可执行的 jar,我们先看看它的结构:

  • sk-website-2.3.6.4.jar:是通过 Spring Boot 打包插件采用新的格式打成 Fat Jar,包含了所有的依赖和资源。
  • sk-website-2.3.6.4.jar.original:是通过 Java 原生的打包方式生成的,仅仅只包含了项目本身的内容。

我们将 sk-website-2.3.6.4.jar 打开,会看到如下结构:

BOOT-INF 文件夹

Spring Boot 定义的目录,用于存放应用程序的内容以及相关依赖。

  • BOOT-INF/classes/

存放编译后的应用程序内容,即对应项目里面的 src/main/java 文件夹内容和资源文件,即对应项目里面的 src/main/resources

  • BOOT-INF/lib/

存放所有外部依赖的 jar 文件。

META-INF 文件夹

主要是包含了 jar 的元数据,文件中的 MANIFEST.MF 包含了启动类的定义和其他 jar 元信息,如下: