Spring Boot使用Spring Boot Gradle Plugin或者Spring Boot Maven Plugin将程序打包成可以独立运行的jar包的。


【资料图】

Spring Boot使用Spring Boot Loader通过java -jar来启动jar包。

我们来解压一下Spring Boot的jar包(jar其实是一个zip文件)

我们可以看到解压的目录下有三个子目录:BOOT-INF,META-INF,org

example.jar | +-META-INF |  +-MANIFEST.MF +-org |  +-springframework |     +-boot |        +-loader |           +- +-BOOT-INF    +-classes    |  +-mycompany    |     +-project    |        +-YourClasses.class    +-lib       +-dependency1.jar       +-dependency2.jar

BOOT-INF

BOOT-INF/classes: 应用程序的classes文件BOOT-INF/lib: 内嵌依赖包BOOT-INF/classpath.idx: jar包添加到classpath的顺序BOOT-INF/layers.idx: 允许将 jar 拆分为逻辑层以创建Docker/OCI镜像

META-INF

META-INF/MANIFEST.MF: 有关jar中包含的文件的信息

org

Spring Boot Loader的classes

探索Spring Boot的魔法

我们将通过一步一步的jar包启动步骤来分析这个过程:

java -jar在META-INF/MANIFEST.MF文件中寻找可执行jar包的入口类:
Manifest-Version: 1.0Main-Class: org.springframework.boot.loader.JarLauncherStart-Class: top.wisely.springasync.SpringAsyncApplicationSpring-Boot-Version: 2.7.2Spring-Boot-Classes: BOOT-INF/classes/Spring-Boot-Lib: BOOT-INF/lib/Spring-Boot-Classpath-Index: BOOT-INF/classpath.idxSpring-Boot-Layers-Index: BOOT-INF/layers.idx
Main-Class: org.springframework.boot.loader.JarLauncher是主入口类.JarLauncher extends ExecutableArchiveLauncher并且ExecutableArchiveLauncher extends LauncherJarLauncher的main方法:
public class JarLauncher extends ExecutableArchiveLauncher {//... public static void main(String[] args) throws Exception {     new JarLauncher().launch(args); }//...}
所以真正的launch(args)方法在Launcher类中:
public abstract class Launcher {  protected void launch(String[] args) throws Exception {     if (!isExploded()) {         JarFile.registerUrlProtocolHandler();      }     ClassLoader classLoader = createClassLoader(getClassPathArchivesIterator()); //①     String jarMode = System.getProperty("jarmode");      String launchClass = (jarMode != null && !jarMode.isEmpty()) ? JAR_MODE_LAUNCHER : getMainClass(); //②     launch(args, launchClass, classLoader);  //③ }}

①classLoader- 创建LaunchedURLClassLoader实例. 所有的BOOT-INF/classes和BOOT-INF/jarclasses 都是由LaunchedURLClassLoader加载。

②launchClass- 从META-INF/MANIFEST.MF获取Start-Class。

③ 使用args,launchClass,classLoader启动应用。

文章出自:​​爱科学的卫斯理​​,如有转载本文请联系爱科学的卫斯理今日头条号。

推荐内容