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

http://docs.spring.io/spring-...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

參考:https://en.wikipedia.org/wiki...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的最前面部分。

https://github.com/spring-pro...

這個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

微信公衆號

橫雲斷嶺的專欄

橫雲斷嶺的專欄

相關文章
相關標籤/搜索