当前位置 主页 > 服务器问题 > Linux/apache问题 >

    Spring Boot 的java -jar命令启动原理详解

    栏目:Linux/apache问题 时间:2020-01-25 17:40

    导语

    在运用Spring Boot 后,我们基本上摆脱之前项目每次上线的时候把项目打成war包。当然也不排除一些奇葩的规定,必须要用war包上线,不过很多时候,我们对一些东西只是处在使用的阶段,并不会去深入的研究使用的原理是什么,这貌似也是大多数人的固定思维。

    或许正是如此,总会有些没有固定思维的人会去积极的探索原理,当然这话不是说我是积极的,我其实也是只原理的搬运工。今天和大家来简单的说下Spring Boot 的项目在运行Java -jar的原理。

    jar包目录和jar命令启动入口

    在正式开始之前,我们先来看看把jar包进行解压。然后用tree /f命令查看目录结构(由于笔者写博文时用的是window,所以用的是tree /f命令),由于目录结构太长,这里做了相应省略,如下:

    ├─BOOT-INF
    │ ├─classes
    │ │ │ application.properties
    │ │ │
    │ │ └─com
    │ │   └─spring
    │ │     └─boot
    │ │       └─test
    │ │           SpringBootTestApplication.class
    │ │
    │ └─lib
    │     classmate-1.5.1.jar
    │     hibernate-validator-6.0.18.Final.jar
    │     …………此处省略…………
    │
    ├─META-INF
    │ │ MANIFEST.MF
    │ │
    │ └─maven
    │   └─com.spring.boot.test
    │     └─spring-boot-test
    │         pom.properties
    │         pom.xml
    │
    └─org
      └─springframework
        └─boot
          └─loader
            │ ExecutableArchiveLauncher.class
            │ JarLauncher.class
            │ LaunchedURLClassLoader$UseFastConnectionExceptionsEnumeration.class
            │ LaunchedURLClassLoader.class
            │ Launcher.class
            │ MainMethodRunner.class
            │ PropertiesLauncher$1.class
            │ PropertiesLauncher$ArchiveEntryFilter.class
            │ PropertiesLauncher$PrefixMatchingArchiveFilter.class
            │ PropertiesLauncher.class
            │ WarLauncher.class
            │
            ├─archive
            │   Archive$Entry.class
            │   …………此处省略…………
            │
            ├─data
            │   RandomAccessData.class
            │   …………此处省略…………
            │
            ├─jar
            │   AsciiBytes.class
            │   Bytes.class
            │   …………此处省略…………
            │
            └─util
                SystemPropertyUtils.class
    

    先简单说下上面目录结构,大体目录分三层:BOOT-INF、META-INF、org,BOOT-INF是存放对应的应用服务的.class文件和Maven依赖的jar包,包括启动类SpringBootTestApplication,META-INF下存放的是Maven相关的pom信息和MANIFEST.MF文件,org文件夹下存放的是Spring boot loader模块编译的.class文件,也就是jar启动的关键代码所在。

    在执行java -jar命令的时候,它的启动类配置实在jar包目录下META-INF文件夹下的名MANIFEST.MF文件中,在这个文件中有一个名为Main-Class的属性,我们来看下这个文件的具体内容:

    Manifest-Version: 1.0
    Implementation-Title: spring-boot-test
    Implementation-Version: 0.0.1-SNAPSHOT
    Start-Class: com.spring.boot.test.SpringBootTestApplication
    Spring-Boot-Classes: BOOT-INF/classes/
    Spring-Boot-Lib: BOOT-INF/lib/
    Build-Jdk-Spec: 1.8
    Spring-Boot-Version: 2.2.3.RELEASE
    Created-By: Maven Archiver 3.4.0
    Main-Class: org.springframework.boot.loader.JarLauncher
    

    从上面的配置文件中,可以看到Main-Class属性指向的Class为org.springframework.boot.loader.JarLauncher,而JarLauncher是JAR的启动器,这个类是在org/springframework/boot/loader/,然后可以看到项目所定义的启动类是指向Start-Class这个属性的。