Spring Boot Executable jar/war 原理

spring boot executable jar/war

spring boot里其实不只能够直接以 java -jar demo.jar的方式启动,还能够把jar/war变为一个能够执行的脚原本启动,好比./demo.jarhtml

把这个executable jar/war 连接到/etc/init.d下面,还能够变为linux下的一个service。java

只要在spring boot maven plugin里配置:linux

<plugin>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-maven-plugin</artifactId>
    <configuration>
        <executable>true</executable>
    </configuration>
</plugin>
复制代码

这样子打包出来的jar/war就是可执行的。更多详细的内容能够参考官方的文档。git

docs.spring.io/spring-boot…github

zip格式里的magic number

生成的jar/war其实是一个zip格式的文件,这个zip格式文件为何能够在shell下面直接执行?spring

研究了下zip文件的格式。zip文件是由entry组成的,而每个entry开头都有一个4个字节的magic number:shell

Local file header signature = 0x04034b50 (read as a little-endian number)

即 PK\003\004
复制代码

参考:en.wikipedia.org/wiki/Zip_(f…bash

zip处理软件是读取到magic number才开始处理。因此在linux/unix下面,能够把一个bash文件直接写在一个zip文件的开头,这样子会被认为是一个bash script。 而zip处理软件在读取这个文件时,仍然能够正确地处理。微信

好比spring boot生成的executable jar/war,的开头是:maven

#!/bin/bash
#
# . ____ _ __ _ _
# /\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
# ( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
# \\/ ___)| |_)| | | | | || (_| | ) ) ) )
# ' |____| .__|_| |_|_| |_\__, | / / / /
# =========|_|==============|___/=/_/_/_/
# :: Spring Boot Startup Script ::
#
复制代码

在script内容结尾,能够看到zip entry的magic number:

exit 0
PK^C^D
复制代码

spring boot的launch.script

实际上spring boot maven plugin是把下面这个script打包到fat jar的最前面部分。

github.com/spring-proj…

这个launch.script 支持不少变量设置。还能够自动识别是处于auto仍是service不一样mode中。

所谓的auto mode就是指直接运行jar/war:

./demo.jar
复制代码

service mode则是由操做系统在启动service的状况:

service demo start/stop/restart/status
复制代码

因此fat jar能够直接在普通的命令行里执行,./xxx.jar 或者link到/etc/init.d/下,变为一个service。

总结

  • jar/war实际就是zip格式
  • spring-boot-maven-plugin把启动脚本打到executable jar/war的最前面
  • 脚本的最后一行是exit 0,脚本只执行本身的内容,不会执行到jar/war里的内容
  • zip文件由多个entry组成,entry的开头有magic number,因此zip处理软件能够跳过前面的脚本,准确找到zip entry

微信公众号

横云断岭的专栏

横云断岭的专栏
相关文章
相关标签/搜索