关于springboot:jvm怎么运行springboot-jar文件的

27次阅读

共计 2290 个字符,预计需要花费 6 分钟才能阅读完成。

前提

对于 springboot 的类加载原理和 spring-boot-loader 的源码解析,网上已有很多的很棒的文章了。我始终置信对于技术原理的获取,代码层面的话肯定是动眼比不上入手,debug跟着源码运行走一遍,成果往往是很棒的。同理,对于 spring-boot-loader 的原理,源码的把握,其原理和 debug 形式参考:springboot jar 包可运行,debug 通知你怎么运行的

本文想要讲述的可能要更近一步了。带着一些疑难开始咱们的学习

  • 1、程序是从哪进入 JarLauncher.main() 办法的
  • 2、java -jar xxx-executable.jar java有什么规定吗
  • 3、jvm层面是如何进入到 java 程序的,连接点在哪里

》本文力求专一和精简,心愿你有所播种和想法

注释

-jar的规矩

其实,java-jar 定义了一些规定,只有合乎这个规定,你做啥都行,怎么做都行。其中的一个是:jar中须要一个 META-INF/MAINFEST.MF 文件,且文件中Main-Class manifest header。官网的阐明如下

所以,咱们解压一个 xxx-executable.jar,会看到META-INF/MAINFEST.MF 的文件及其内容

正是因为有了 Main-Class: org.springframework.boot.loader.JarLauncher,所以,当java -jar xxx-executable.jar 时,程序会进入 org.springframework.boot.loader.JarLauncher 执行 main 办法。到这里我又有了疑难,那是从哪进入 JarLauncher.main 办法的呢

程序是怎么进入 JarLauncher.main 办法的呢

这个时候想到了 jvm。应该是从jvm 进去到了JarLauncher.main,那么怎么验证呢。

咱们通过 CLion 查看 jvm 源码,试图找到这个答案。咱们通过全局搜寻 Main-Class,Manifest 这些关键词来定位所在的文件,并打上相应的debug 端点。如下图

而后咱们启动 debug 模式启动 jvm,启动时配置上咱们的利用jar 包:-jar xxx-executable.jar,如下图

当初咱们跟着 jvmdebug一起追下寻找Main-Class,Manifest 的过程。

看到了JLI_ParseManifest,从名字也看的进去这个头绪了

能够看到 static const char *manifest_name = "META-INF/MANIFEST.MF" 在 jvm 中是个常量。所以,咱们的利用 xxx-executable.jar 中必须有个叫这个名的目录和文件。办法接着解析了这个文件,文件的内容和咱们解压 xxx-executable.jar 看到的内容统一,如下图

所以,到这 Main-Class 的值就被解析进去了。上面咱们看下 jvm 如何加载 Main-Class 的值 (即 o rg.springframework.boot.loader.JarLauncher) 的。

上面图中 6 个局部其实将虚拟机的整个初始化和加载过程都显示进去了。在这里咱们只关注 JarLauncher 是如何加载初始化与 JarLauncher.main 是怎么运行的,所以咱们重点关注(1)、(2)、(4)、(6)

(1)LoadMainClass – 加载main class

咱们先看下 LoadMainClass 的细节,看看她咋加载的。通过 GetLauncherHelperClass 办法,咱们终于看到了相熟的身影:sun/launcher/LauncherHelper 这个java class。如下图

LoadMainClass做了三件事:
1、获取 LauncherHelper 实例
2、通过checkAndLoadMain 办法应用 ClassLoader.getSystemClassLoader 初始化 org.springframework.boot.loader.JarLauncher class
3、makePlatformString 获取 utf-8 后的string

须要特地指出的是 LauncherHelper.java。这个类的源码在jvm 中,在咱们相熟的 rt.jar 是以 .class 的模式呈现的。我把他俩放在一张图片里比照下

(2)获取 LauncherHelper 的实例

这里的实例是在 (1) 中初始化好的,用就好了

(4)验证和加载 main 办法

这里用了相似反射的办法来获取 main 办法

(6)调用 LauncherHelper.main 办法

这里就是咱们始终要晓得的那个中央,也是文章结尾局部的问题 1 和 3 的答案。即 jvm 运行和 java application 的连接点。利用 CLionIdea,利用debug,我人为的把他俩的运行联合在一起,具象的示意出这两个点的运行,如下图

it`s time to summary

到这里,咱们的疑难都找到答案了。咱们从 jvm 源码到 java 代码,整个流程串下来。置信有人再问你 springboot 的入口时,你不仅晓得了是 JarLauncher.main,而且能进一步晓得从哪(怎么) 进入的 JarLauncher.main 的。这不论是对工作,还是面试,对你都是有很大收益的。

原味地址:jvm 怎么运行 springboot jar 文件的

附录

所有,从 jvmspringboot,再到利用 app 的入口,咱们当初都晓得了。

java.c 的 JavaMain 办法 --> LauncherHelper.java 的 main 办法 --> Application.java 的 main 办法

正文完
 0