今天我們要介紹的是spring-native,它可以讓你的spring boot程序,體驗graalvm編譯器的特性,把你的應用直接編譯成native的!
不需要再安裝jre,你的應用程序將和exe一樣,直接在目標機器上運行!而且啟動時間不到1秒鐘。
要體驗這個功能,我們從spring boot拿一個demo。
https://start.spring.io/
在這裡選擇這個實驗性的功能SpringNative。下載下來之後,就可以使用maven進行打包測試。

mvn spring-boot:build-image
gradle bootBuildImage
看一下這無敵的啟動速度…. 0.038秒… 幾乎是瞬時的!

神奇!
這一切,都得益於graalvm編譯器。不過,你至少要把JDK升級到11才能用,也算是堆Java8用戶的一種別樣的驅動吧。
當然,只有在2.4.5以後的SpringBoot版本中,才支持Spring Native。
GraalVM是什麼?
graalvm也是oracle的項目,它的代碼地址是:
mvn spring-boot:build-image
gradle bootBuildImage
項目地址是:
www.graalvm.org/docs/
graalvm是一個想要統一天下的虛擬機。因為它相比較與HotSpotVM,還能夠運行其他語言比如ruby,python,php等。
它是一個新的JVM,不同的是由於做了適配,它能夠讓不同的語言跑在同一個vm下面。
看看下面這張圖,就知道graalvm的野心有多大。

這還沒完,它最吸引人的地方就在於,它能夠將應用代碼,直接打包成native的二進位可執行代碼,運行時連JVM都不需要了!
大家都知道,native和跑在vm里完全是兩個檔次,否則也不會有jit這麼牛x的技術存在了。連android和ios都知道,native的應用流暢性比跑在monotouch上或者hybrid上高很多很多,對於追求性能的企業級應用來說,這個功能就更加實用一些。
讓人驚訝的是,它為各個語言實現了一個可以溝通的橋樑。比如我看好js中的某個庫,不需要重新開發一個了,在Java中直接就可以用。這是因為,graalVM開發了跨語言互操作協議,能保證跨語言的互操作性。
現在這個功能,大多數平台已經支持了。

public class Example {
public static void main(String[] args) {
String str = "Native Image is awesome";
String reversed = reverseString(str);
System.out.println("The reversed string is: " + reversed);
}
public static String reverseString(String str) {
if (str.isEmpty())
return str;
return reverseString(str.substring(1)) + str.charAt(0);
}
}
通常情況下,我們直接這樣運行,或者打包成jar包。
javac Example.java
java Example
但我們還可以多一步,就是把class文件native化。
native-image Example
執行的時候,只需要輸入 ./Example 就可以了。
有什麼好處?
使用native編譯的應用,可以實現秒級別的啟動,運行更快,佔用內存更小。它與主流的部署方式如微服務、k8s等,更加的切合。
但它與傳統的JVM也有很多不同,主要體現在:
- 系統的性能分析會在編譯階段就給出
- 沒用的部分和代碼將不會編譯,直接會被移除,這得益於前些java版本的模塊化
- 需要提前對反射、資源和動態代理進行轉換,沒有類載入的延遲
- classpath在編譯階段固定
- class將不會被懶載入,回在啟動的時候一股腦放到內存
雖然native有很多好處,但它的編譯時間卻很長,因為要做大量的代碼靜態分析,這也是所有native程序的通病吧。
End
這種thin jar的思路,是不是感覺Java的發展越來越像golang了呢?docker鏡像也會因為這種改變便得更小更純粹,而脫離jre的Java應用也越來越像一個真正的程序了。
但可惜的是,這種編譯成native的思路雖然好,現階段還是無法和golang相抗衡,主要還是在於編譯器的差異上。
但願graalvm能夠繼續發力,帶java繼續飛上幾十年,養我三代子孫!
原創文章,作者:投稿專員,如若轉載,請註明出處:https://www.506064.com/zh-tw/n/269724.html