当执行 java -jar springBootDemo.jar 后发生了什么 —— 1. 如何认识我们的jar包?

前言

现在Java界最流行的就是SpringBoot框架,无需再打包成war包丢到tomcat的webapps目录下面去,启动tomcat才能看到web应用。现在,一句简单的 java -jar springBootDemo.jar 即可启动web应用,那这里面都发生了什么呢?

得注意一个前提,jar包里面都是已经编译好的class文件,可以直接虚拟机运行,因此不需要考虑编译相关的内容。

参考资料
https://juejin.im/post/5d16cc8cf265da1b8d163237(聊一聊 JAR 文件和 MANIFEST.MF)

1. springBootDemo.jar 里面包括什么?

具体来看看jar包里面都包含了什么信息

BOOT-INF/
    - classes/    编写的java代码以及配置文件所在处
    - lib/    依赖的jar包们
META-INF/
    - maven/    工程相关的maven配置,如pom.xml
    - MANIFES.MF    工程启动类等相关信息定义
    - spring-configuration-metadata.json    工程需要的配置项,如@Value等值
org/
    - springframework/    实际Main-Class所在位置,可在GitHub下载源代码
2. MANIFES.MF 文件解读

目前正在使用的一个工程的MANIFES.MF文件如下

Manifest-Version: 1.0
Implementation-Title: ms-business-basic
Implementation-Version: 0.0.1-PHSP-SNAPSHOT
Start-Class: com.demo.basic.common.BaseServiceApplication  //表明工程的启动类
Spring-Boot-Classes: BOOT-INF/classes/
Spring-Boot-Lib: BOOT-INF/lib/
Build-Jdk-Spec: 1.8
Spring-Boot-Version: 2.1.9.RELEASE
Created-By: Maven Archiver 3.4.0
Main-Class: org.springframework.boot.loader.JarLauncher    // MAIN函数

其中Main-Class 指定程序的入口,这样可以直接用java -jar xxx.jar来运行程序

JDK 中提供了可以获取 jar 包中 MANIFEST.MF 文件信息的工具,可以通过 java.util.jar 这个类库来获取。

3. Main-Class:JarLauncher 分析

参考资料
SpringBoot的运行机制

现在假设,java -jar 命令之后,则执行Main-Class进行工程的启动。

通过工具jd-gui查看class文件得出内容如下

package org.springframework.boot.loader;

import org.springframework.boot.loader.archive.Archive;
import org.springframework.boot.loader.archive.Archive.Entry;

public class JarLauncher extends ExecutableArchiveLauncher
{
  static final String BOOT_INF_CLASSES = "BOOT-INF/classes/";
  static final String BOOT_INF_LIB = "BOOT-INF/lib/";

  public JarLauncher()
  {
  }

  protected JarLauncher(Archive archive)
  {
    super(archive);
  }

  protected boolean isNestedArchive(Archive.Entry entry)
  {
    if (entry.isDirectory()) {
      return entry.getName().equals("BOOT-INF/classes/");
    }
    return entry.getName().startsWith("BOOT-INF/lib/");
  }

  public static void main(String[] args) throws Exception {
    new JarLauncher().launch(args);
  }
}

但是在jd-gui反编译工具里面并未看到ExecutableArchiveLauncher文件,实际上看jar里面是存在该class文件的,不过再一次尝试的时候,反编译工具说该class文件invalid。

不过官方已经把该代码开源,可以去GitHub上找到,地址

https://github.com/spring-projects/spring-boot/tree/master/spring-boot-project/spring-boot-tools/spring-boot-loader/src/main/java/org/springframework/boot/loader

然后我们下一个章节继续分析究竟里面做了什么?

4. SpringBoot官方代码仓库

GitHub地址如下:
https://github.com/spring-projects/spring-boot

可以把代码拷贝下来在IDEA里面看一看,能够看到jar包内org/springframewok内的源代码

你可能感兴趣的:(Java,SpringBoot)