SpringBoot3+graalvm:整合并打包為可執(zhí)行文件方式
簡(jiǎn)介
本文介紹SpringBoot3如何整合graalvm,并打包為可執(zhí)行文件。Windows和Linux都打包。
版本
- springboot3.3.6
- graalvm21(包含JDK21(21是最新的LTS版本,SpringBoot3最低要求JDK17))
安裝graalvm
1.下載
官網(wǎng):https://www.graalvm.org/
進(jìn)去后點(diǎn)擊下載,即可找到:
下載后得到此文件:graalvm-jdk-21_windows-x64_bin.zip
(JDK21不需要下載native-image了,因?yàn)橐呀?jīng)捆綁到bin目錄了。直接在bin目錄下cmd輸入native-image即可)
2.安裝
將graalvm-jdk-21_windows-x64_bin.zip解壓到指定目錄,我這里解壓到:E:\work\develop_env\graalvm\graalvm-jdk-21_windows-x64_bin
把JDK環(huán)境變量配置為GraalVM的路徑(因?yàn)镚raalVM就是JDK)。
由于我要同時(shí)用JDK8和JDK21,所以要配置一下,見(jiàn):Windows使用多個(gè)JDK的方法
創(chuàng)建SpringBoot項(xiàng)目
跟原來(lái)SpringBoot2的項(xiàng)目結(jié)構(gòu)是一樣的。
依賴(lài)及代碼
pom.xml
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>3.3.6</version> <relativePath/> <!-- lookup parent from repository --> </parent> <groupId>com.knife</groupId> <artifactId>Demo_SpringBoot3</artifactId> <version>0.0.1-SNAPSHOT</version> <name>Demo_SpringBoot3</name> <description>Demo project for Spring Boot3</description> <properties> <java.version>21</java.version> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <scope>provided</scope> </dependency> </dependencies> <build> <plugins> <!-- AOT Graalvm 插件 --> <plugin> <groupId>org.graalvm.buildtools</groupId> <artifactId>native-maven-plugin</artifactId> </plugin> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <!-- <version>3.5.1</version> --> <!-- 指定maven編譯的jdk版本。對(duì)于JDK8,寫(xiě)成8或者1.8都可以 --> <configuration> <source>${java.version}</source> <target>${java.version}</target> </configuration> </plugin> </plugins> </build> </project>
Controller
package com.knife.example.controller; import lombok.extern.slf4j.Slf4j; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; @Slf4j @RequestMapping("test") @RestController public class HelloController { @GetMapping("test1") public String test1() { return "success"; } }
啟動(dòng)與測(cè)試
啟動(dòng)
Connected to the target VM, address: '127.0.0.1:52251', transport: 'socket'
. ____ _ __ _ _
/\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
\\/ ___)| |_)| | | | | || (_| | ) ) ) )
' |____| .__|_| |_|_| |_\__, | / / / /
=========|_|==============|___/=/_/_/_/:: Spring Boot :: (v3.3.6)
2024-11-29T15:09:52.849+08:00 INFO 43480 --- [ main] com.knife.example.DemoApplication : Starting DemoApplication using Java 21.0.5 with PID 43480 (E:\project\Idea_Proj\Demo_Java\Demo_SpringBoot3\target\classes started by aaabbb in E:\project\Idea_Proj\Demo_Java\Demo_SpringBoot3)
2024-11-29T15:09:52.852+08:00 INFO 43480 --- [ main] com.knife.example.DemoApplication : No active profile set, falling back to 1 default profile: "default"
2024-11-29T15:09:53.549+08:00 INFO 43480 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat initialized with port 8080 (http)
2024-11-29T15:09:53.561+08:00 INFO 43480 --- [ main] o.apache.catalina.core.StandardService : Starting service [Tomcat]
2024-11-29T15:09:53.562+08:00 INFO 43480 --- [ main] o.apache.catalina.core.StandardEngine : Starting Servlet engine: [Apache Tomcat/10.1.33]
2024-11-29T15:09:53.612+08:00 INFO 43480 --- [ main] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring embedded WebApplicationContext
2024-11-29T15:09:53.613+08:00 INFO 43480 --- [ main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 715 ms
2024-11-29T15:09:53.925+08:00 INFO 43480 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat started on port 8080 (http) with context path '/'
2024-11-29T15:09:53.933+08:00 INFO 43480 --- [ main] com.knife.example.DemoApplication : Started DemoApplication in 1.439 seconds (process running for 2.028)
2024-11-29T15:09:56.814+08:00 INFO 43480 --- [nio-8080-exec-1] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring DispatcherServlet 'dispatcherServlet'
2024-11-29T15:09:56.814+08:00 INFO 43480 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet : Initializing Servlet 'dispatcherServlet'
2024-11-29T15:09:56.815+08:00 INFO 43480 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet : Completed initialization in 1 ms
測(cè)試接口
訪(fǎng)問(wèn):http://localhost:8080/test/test1
結(jié)果:
打包為可執(zhí)行文件(Windows的.exe)
從上邊來(lái)看,好像與SpringBoot2沒(méi)啥區(qū)別。但SpringBoot3有一個(gè)重要改動(dòng):可以打包為可執(zhí)行文件,比如:Windows的.exe文件,可以直接執(zhí)行。性能強(qiáng)、啟動(dòng)快、占內(nèi)存低。
下邊就實(shí)戰(zhàn)一下打包為可執(zhí)行文件。
1.下載Visual Studio組件
Windows使用native-image 打包需要C++環(huán)境,VisualStudio 可以提供c++開(kāi)發(fā)環(huán)境,所以我們要先下載安裝好VisualStudio。
必須安裝VisualStudio組件,否則在下邊mvn -Pnative native:compile時(shí)會(huì)報(bào)錯(cuò):
Error: Failed to find 'vcvarsall.bat' in a Visual Studio installation.
Please make sure that Visual Studio 2022 version 17.1.0 or later is installed on your system. You can download it at https://visualstudio.microsoft.com/downloads/. If this error persists, please try and run GraalVM Native Image in an x64 Native Tools Command Prompt or file a ticket.
下載
地址:https://visualstudio.microsoft.com/zh-hans/
進(jìn)去后點(diǎn)擊這里:
點(diǎn)擊完后,會(huì)自動(dòng)下載VisualStudioSetup.exe
2.安裝Visual Studio組件
雙擊VisualStudioSetup.exe,點(diǎn)擊繼續(xù),然后到如下界面:
選擇正確版本的SDK
運(yùn)行cmd,輸入VER并回車(chē),即可得到版本,找最接近的即可。
選擇英文語(yǔ)言包
修改安裝位置:
注意:記住這個(gè)位置,后邊要用。
最后點(diǎn)擊安裝:
正在安裝:
安裝完成
如果上邊有操作錯(cuò)誤,可以點(diǎn)擊修改:
刪除無(wú)用的安裝包,之前選定了下載緩存,把它刪掉,我的目錄是:
D:\ProgramData\Microsoft\VisualStudio\Packages
3.配置環(huán)境變量
配置VS環(huán)境變量
1.新建VISUAL_STUDIO系統(tǒng)變量
指定到自己的VS路徑
2.Path添加VISUAL_STUDIO的bin路徑
即:%VISUAL_STUDIO%\VC\Tools\MSVC\14.42.34433\bin\Hostx64\x64
3. 添加INCLUDE環(huán)境變量
我上邊設(shè)置的套件安裝位置是:E:\work\develop_env\visual_studio,Windows Kits自動(dòng)安裝到了這里:E:\Windows Kits。為統(tǒng)一管理,我把E:\Windows Kits復(fù)制到E:\work\develop_env\visual_studio\下邊。
(如果沒(méi)改過(guò)路徑,那會(huì)在這個(gè)路徑下:C:\Program Files (x86)\Windows Kits\)
然后添加環(huán)境變量:
%VISUAL_STUDIO%\VC\Tools\MSVC\14.42.34433\include;E:\work\develop_env\visual_studio\Windows Kits\10\Include\10.0.19041.0\shared;E:\work\develop_env\visual_studio\Windows Kits\10\Include\10.0.19041.0\ucrt;E:\work\develop_env\visual_studio\Windows Kits\10\Include\10.0.19041.0\um;E:\work\develop_env\visual_studio\Windows Kits\10\Include\10.0.19041.0\winrt
即:
4.添加lib環(huán)境變量
與上邊INCLUDE類(lèi)似。
添加lib環(huán)境變量,值為:
%VISUAL_STUDIO%\VC\Tools\MSVC\14.42.34433\lib\x64;E:\work\develop_env\visual_studio\Windows Kits\10\Lib\10.0.19041.0\ucrt\x64;E:\work\develop_env\visual_studio\Windows Kits\10\Lib\10.0.19041.0\um\x64
即:
4.打包
打包的步驟如下。
mvn clean mvn compile mvn spring-boot:process-aot mvn -Pnative native:compile
第四步才會(huì)生成.jar和.exe文件。
以上四個(gè)步驟,可以在Idea里運(yùn)行(但是必須在上一步配置完環(huán)境變量后,重啟Idea,否則環(huán)境變量不生效?。?/p>
結(jié)果:
主要步驟
[1/8] Initializing...
[2/8] Performing analysis...
[3/8] Building universe...
[4/8] Parsing methods...
[5/8] Inlining methods...
[6/8] Compiling methods...
[7/8] Layouting methods...
[8/8] Creating image...
看結(jié)果文件:
對(duì)比一下jar和exe大?。海?exe文件竟然是.jar的四倍)
備注
有人說(shuō)必須用官方命令行工具,不能用Idea等,其實(shí)是因?yàn)榕渲猛戥h(huán)境變量后沒(méi)有重啟Idea,導(dǎo)致沒(méi)編譯成功。
官方雖然有說(shuō)明:
但是,只要重啟Idea,就能直接用Idea去通過(guò)點(diǎn)擊直接操作!
5.運(yùn)行.exe
直接雙擊Demo_SpringBoot3.exe即可運(yùn)行:
測(cè)試一下它的接口:(成功訪(fǎng)問(wèn))
6.對(duì)比內(nèi)存占用
先看上邊.exe的內(nèi)存占用:
把它關(guān)掉,運(yùn)行一下jar看一下
可見(jiàn),單純看.exe和.jar的內(nèi)存占用的話(huà):
- .exe:29MB
- .jar:154MB
打包為可執(zhí)行文件(Linux)
目標(biāo):打包為Ubuntu的可執(zhí)行文件,本處我的Ubuntu版本:2022.04.04,x86_64架構(gòu)。
備注:無(wú)法在Windows下交叉編譯,只能到Linux里直接編譯。
1.下載graalvm(Linux版)
官網(wǎng):https://www.graalvm.org/
進(jìn)去后點(diǎn)擊下載,即可找到:
我的Ubuntu是x86_64,所以下載這個(gè):
下載后得到此文件:graalvm-jdk-21_linux-x64_bin.tar.gz
(JDK21不需要下載native-image了,因?yàn)橐呀?jīng)捆綁到bin目錄了)
2.配置Ubuntu宿主機(jī)環(huán)境變量
將上邊文件上傳到Ubuntu宿主機(jī),這里我上傳到此路徑:/work/env/graalvm/
解壓一下:
tar xf graalvm-jdk-21_linux-x64_bin.tar.gz
解壓之后:
執(zhí)行兩條命令:
export JAVA_HOME=/work/env/graalvm/graalvm-jdk-21.0.5+9.1 export PATH=$PATH:$JAVA_HOME/bin
執(zhí)行一下java看看:
3.用Docker搭建maven
見(jiàn):Docker Compose--安裝本地maven
4.Maven容器配置環(huán)境變量
將graalvm復(fù)制到maven容器路徑:這里我復(fù)制到:/work/env/maven/tool/graalvm/
執(zhí)行兩條命令:
export JAVA_HOME=/tool/graalvm/graalvm-jdk-21.0.5+9.1 export PATH=$PATH:$JAVA_HOME/bin
驗(yàn)證Java版本:java -version
驗(yàn)證native-image:native-image --version
5.Maven容器安裝編譯工具
apt update apt install build-essential libz-dev zlib1g-dev
native-image要用到二進(jìn)制編譯工具,所以要安裝編譯工具。
6.Maven容器打包
將項(xiàng)目上傳到Linux服務(wù)器,然后把它打包為二進(jìn)制文件。
先把項(xiàng)目打包:tar czf Demo_SpringBoot3.tar.gz Demo_SpringBoot3/
我直接用Windows下的git bash工具:
把Demo_SpringBoot3.tar.gz上傳到Linux服務(wù)器。
我放到此目錄:/work/env/maven/app。將其解壓:
tar xf Demo_SpringBoot3.tar.gz
結(jié)果:
進(jìn)入maven容器
docker exec -it maven_3.9 bash
進(jìn)入/app/Demo_SpringBoot3執(zhí)行打包命令:
mvn clean mvn compile mvn spring-boot:process-aot mvn -Pnative native:compile
結(jié)果(用的虛擬機(jī),運(yùn)行有點(diǎn)慢,用了十幾分鐘):
7.運(yùn)行可執(zhí)行文件
進(jìn)入宿主機(jī),進(jìn)入target目錄:/work/env/maven/app/Demo_SpringBoot3/target
執(zhí)行:./Demo_SpringBoot3
訪(fǎng)問(wèn): http://192.168.5.193:8080/test/test1
成功!
8.對(duì)比內(nèi)存占用
看二進(jìn)制執(zhí)行時(shí)的占用:
關(guān)掉它,執(zhí)行一下.jar試試
可見(jiàn),物理內(nèi)存占用:
- 二進(jìn)制:80m
- .jar:169m總結(jié)
總結(jié)
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
Spring MVC 關(guān)于controller的字符編碼問(wèn)題
在使用springMVC框架構(gòu)建web應(yīng)用,客戶(hù)端常會(huì)請(qǐng)求字符串、整型、json等格式的數(shù)據(jù),通常使用@ResponseBody注解使 controller回應(yīng)相應(yīng)的數(shù)據(jù)而不是去渲染某個(gè)頁(yè)面。2017-03-03SpringBoot2.x實(shí)現(xiàn)給Controller的RequestMapping添加統(tǒng)一前綴
這篇文章主要介紹了SpringBoot2.x實(shí)現(xiàn)給Controller的RequestMapping添加統(tǒng)一前綴,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-02-02Java?Map初始化并賦值的幾種簡(jiǎn)短寫(xiě)法
在Java中初始化一個(gè)Map并賦值可以通過(guò)多種方式完成,下面這篇文章主要介紹了Java?Map初始化并賦值的幾種簡(jiǎn)短寫(xiě)法,文中給出了詳細(xì)的代碼示例,需要的朋友可以參考下2025-03-03解決springboot項(xiàng)目啟動(dòng)報(bào)錯(cuò)Field xxxMapper in com...xx
這篇文章主要介紹了解決springboot項(xiàng)目啟動(dòng)報(bào)錯(cuò)Field xxxMapper in com...xxxContr問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-12-12Spring IOC的三種實(shí)現(xiàn)方式詳解
這篇文章主要介紹了Spring IOC的三種實(shí)現(xiàn)方式,在Spring框架中,IOC通過(guò)依賴(lài)注入來(lái)實(shí)現(xiàn),而依賴(lài)注入主要有三種實(shí)現(xiàn)方式,構(gòu)造器注入、Setter注入和字段注入,每種方式都有其特點(diǎn)、適用場(chǎng)景和優(yōu)缺點(diǎn),需要的朋友可以參考下2025-02-02java實(shí)現(xiàn)合并兩個(gè)已經(jīng)排序的列表實(shí)例代碼
這篇文章主要介紹了java實(shí)現(xiàn)合并兩個(gè)已經(jīng)排序的列表實(shí)例代碼,有需要的朋友可以參考一下2013-12-12SpringSecurity oAuth2.0的四種模式(小結(jié))
本文主要介紹了SpringSecurity oAuth2.0的四種模式,文中通過(guò)示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-02-02SpringBoot使用Nacos配置中心的實(shí)現(xiàn)
這篇文章主要介紹了SpringBoot使用Nacos配置中心的實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-12-12