【SpringBoot】SpringBoot3.0 云原生时代即将来临!

InterviewCoder

# 【SpringBoot】SpringBoot3.0 云原生时代即将来临!

云原生时代的Spring Boot 3.0: GraalVM原生镜像,启动速度提升近30倍

# 云原生时代的 Spring Boot 3.0: GraalVM 原生镜像,启动速度提升近 30 倍

InterviewCoder

# Spring Boot 3.0 于(2022 年 11 月 24 日)发布,变化很大,基于 spring6.0,spring6.0 是 Spring 下一个未来十年的新开端。

# JAVA 17

Spring Boot 3.0 版本最低支持 Java17,Springboot 2.7.3 最常用的 jdk 版本是 Java 8,现在直接跳了 9 个版本直接从 8 跳到了 17,且是强制要求,必须 17 或 17 以上的 java 版本。所以以后开发可以用上 17 或 17 以上的 Java 语言的新特性。

# Spring Native

Spring Native 也是升级的一个重大特性,支持使用 GraalVM 将 Spring 的应用程序编译成本地可执行的镜像文件,可以显著提升启动速度、峰值性能以及减少内存使用。

我们传统的应用都是编译成字节码,然后通过 JVM 解释并最终编译成机器码来运行,而 Spring Native 则是通过 AOT 提前编译为机器码,在运行时直接静态编译成可执行文件,不依赖 JVM。

img

# Jakarta EE

JavaEE 改名之后就叫 JakartaEE,比如我们之前的 javax.servlet 包现在就叫 jakarta.servlet。也因此,代码中所有使用到比如 HttpServletRequest 对象的 import 都需要修改。

1
2
3
import javax.servlet.http.HttpServletRequest;
// 改为
import jakarta.servlet.http.HttpServletRequest;

# Spring Boot 3.0 初步使用(Windows)

创建 Spring Boot 3.0 项目有两种方式,一种是 Idea 直接创建。

img

img

若 IDE 不是最新版本,不支持创建 Spring Boot 3.0,还有第二种方式创建 Spring Boot 3.0 项目,登录官网 https://start.spring.io/ 生成 Spring Boot 3.0 初始项目。

img

下面是 Spring Boot 3.0 的最小 pom 文件内容:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
<?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.0.0</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.example</groupId>
<artifactId>demo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>demo</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>17</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<version>3.0.0</version>
<scope>compile</scope>
</dependency>
</dependencies>

<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>

</project>

运行 spring boot 项目,需要安装开发环境,spring boot 3.0 开始不用 jdk 了,取而代之的是 graalvm,且最低版本要求是 java17 graalvm 版本。

https://github.com/graalvm/graalvm-ce-builds/releases 下载对应操作系统的 java17 graalvm 版本。

1
2
3
4
PS C:\Users\hanwei> java --version
openjdk 17.0.5 2022-10-18
OpenJDK Runtime Environment GraalVM CE 22.3.0 (build 17.0.5+8-jvmci-22.3-b08)
OpenJDK 64-Bit Server VM GraalVM CE 22.3.0 (build 17.0.5+8-jvmci-22.3-b08, mixed mode, sharing)

在最小 Spring Boot 项目源码的基础上了个简单的 controller。

img

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
package com.example.demo.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

@Controller
public class QuickStartController {
@RequestMapping("/test")
@ResponseBody
public String test(){
return "springboot 3.0 访问测试";
}

@RequestMapping("/hello")
@ResponseBody
public String home(){
return "Hello World from springboot 3.0!";
}
}

用 java17 graalvm 编译运行 demo 项目。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
C:\sdk\graalvm-ce-java17-22.3.0\bin\java.exe -XX:TieredStopAtLevel=1 -Dspring.output.ansi.enabled=always -Dcom.sun.management.jmxremote -Dspring.jmx.enabled=true -Dspring.liveBeansView.mbeanDomain -Dspring.application.admin.enabled=true "-javaagent:C:\Program Files\JetBrains\IntelliJ IDEA 2022.2\lib\idea_rt.jar=9872:C:\Program Files\JetBrains\IntelliJ IDEA 2022.2\bin" -Dfile.encoding=UTF-8 -classpath C:\Users\hanwei\Documents\JavaProject\demo-maven\target\classes;C:\Users\hanwei\.m2\repository\org\springframework\boot\spring-boot-starter\3.0.0\spring-boot-starter-3.0.0.jar;C:\Users\hanwei\.m2\repository\org\springframework\boot\spring-boot\3.0.0\spring-boot-3.0.0.jar;C:\Users\hanwei\.m2\repository\org\springframework\spring-context\6.0.2\spring-context-6.0.2.jar;C:\Users\hanwei\.m2\repository\org\springframework\boot\spring-boot-autoconfigure\3.0.0\spring-boot-autoconfigure-3.0.0.jar;C:\Users\hanwei\.m2\repository\org\springframework\boot\spring-boot-starter-logging\3.0.0\spring-boot-starter-logging-3.0.0.jar;C:\Users\hanwei\.m2\repository\ch\qos\logback\logback-classic\1.4.5\logback-classic-1.4.5.jar;C:\Users\hanwei\.m2\repository\ch\qos\logback\logback-core\1.4.5\logback-core-1.4.5.jar;C:\Users\hanwei\.m2\repository\org\apache\logging\log4j\log4j-to-slf4j\2.19.0\log4j-to-slf4j-2.19.0.jar;C:\Users\hanwei\.m2\repository\org\apache\logging\log4j\log4j-api\2.19.0\log4j-api-2.19.0.jar;C:\Users\hanwei\.m2\repository\org\slf4j\jul-to-slf4j\2.0.4\jul-to-slf4j-2.0.4.jar;C:\Users\hanwei\.m2\repository\jakarta\annotation\jakarta.annotation-api\2.1.1\jakarta.annotation-api-2.1.1.jar;C:\Users\hanwei\.m2\repository\org\springframework\spring-core\6.0.2\spring-core-6.0.2.jar;C:\Users\hanwei\.m2\repository\org\springframework\spring-jcl\6.0.2\spring-jcl-6.0.2.jar;C:\Users\hanwei\.m2\repository\org\yaml\snakeyaml\1.33\snakeyaml-1.33.jar;C:\Users\hanwei\.m2\repository\org\slf4j\slf4j-api\2.0.4\slf4j-api-2.0.4.jar;C:\Users\hanwei\.m2\repository\org\springframework\boot\spring-boot-starter-web\3.0.0\spring-boot-starter-web-3.0.0.jar;C:\Users\hanwei\.m2\repository\org\springframework\boot\spring-boot-starter-json\3.0.0\spring-boot-starter-json-3.0.0.jar;C:\Users\hanwei\.m2\repository\com\fasterxml\jackson\core\jackson-databind\2.14.1\jackson-databind-2.14.1.jar;C:\Users\hanwei\.m2\repository\com\fasterxml\jackson\core\jackson-annotations\2.14.1\jackson-annotations-2.14.1.jar;C:\Users\hanwei\.m2\repository\com\fasterxml\jackson\core\jackson-core\2.14.1\jackson-core-2.14.1.jar;C:\Users\hanwei\.m2\repository\com\fasterxml\jackson\datatype\jackson-datatype-jdk8\2.14.1\jackson-datatype-jdk8-2.14.1.jar;C:\Users\hanwei\.m2\repository\com\fasterxml\jackson\datatype\jackson-datatype-jsr310\2.14.1\jackson-datatype-jsr310-2.14.1.jar;C:\Users\hanwei\.m2\repository\com\fasterxml\jackson\module\jackson-module-parameter-names\2.14.1\jackson-module-parameter-names-2.14.1.jar;C:\Users\hanwei\.m2\repository\org\springframework\boot\spring-boot-starter-tomcat\3.0.0\spring-boot-starter-tomcat-3.0.0.jar;C:\Users\hanwei\.m2\repository\org\apache\tomcat\embed\tomcat-embed-core\10.1.1\tomcat-embed-core-10.1.1.jar;C:\Users\hanwei\.m2\repository\org\apache\tomcat\embed\tomcat-embed-el\10.1.1\tomcat-embed-el-10.1.1.jar;C:\Users\hanwei\.m2\repository\org\apache\tomcat\embed\tomcat-embed-websocket\10.1.1\tomcat-embed-websocket-10.1.1.jar;C:\Users\hanwei\.m2\repository\org\springframework\spring-web\6.0.2\spring-web-6.0.2.jar;C:\Users\hanwei\.m2\repository\org\springframework\spring-beans\6.0.2\spring-beans-6.0.2.jar;C:\Users\hanwei\.m2\repository\io\micrometer\micrometer-observation\1.10.2\micrometer-observation-1.10.2.jar;C:\Users\hanwei\.m2\repository\io\micrometer\micrometer-commons\1.10.2\micrometer-commons-1.10.2.jar;C:\Users\hanwei\.m2\repository\org\springframework\spring-webmvc\6.0.2\spring-webmvc-6.0.2.jar;C:\Users\hanwei\.m2\repository\org\springframework\spring-aop\6.0.2\spring-aop-6.0.2.jar;C:\Users\hanwei\.m2\repository\org\springframework\spring-expression\6.0.2\spring-expression-6.0.2.jar com.example.demo.DemoApplication

. ____ _ __ _ _
/\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
\\/ ___)| |_)| | | | | || (_| | ) ) ) )
' |____| .__|_| |_|_| |_\__, | / / / /
=========|_|==============|___/=/_/_/_/
:: Spring Boot :: (v3.0.0)

2022-11-29T10:19:58.816+08:00 INFO 20116 --- [ main] com.example.demo.DemoApplication : Starting DemoApplication using Java 17.0.5 with PID 20116 (C:\Users\hanwei\Documents\JavaProject\demo-maven\target\classes started by hanwei in C:\Users\hanwei\Documents\JavaProject\demo-maven)
2022-11-29T10:19:58.818+08:00 INFO 20116 --- [ main] com.example.demo.DemoApplication : No active profile set, falling back to 1 default profile: "default"
2022-11-29T10:19:59.501+08:00 INFO 20116 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat initialized with port(s): 8080 (http)
2022-11-29T10:19:59.510+08:00 INFO 20116 --- [ main] o.apache.catalina.core.StandardService : Starting service [Tomcat]
2022-11-29T10:19:59.510+08:00 INFO 20116 --- [ main] o.apache.catalina.core.StandardEngine : Starting Servlet engine: [Apache Tomcat/10.1.1]
2022-11-29T10:19:59.594+08:00 INFO 20116 --- [ main] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring embedded WebApplicationContext
2022-11-29T10:19:59.594+08:00 INFO 20116 --- [ main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 737 ms
2022-11-29T10:19:59.866+08:00 INFO 20116 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat started on port(s): 8080 (http) with context path ''
2022-11-29T10:19:59.872+08:00 INFO 20116 --- [ main] com.example.demo.DemoApplication : Started DemoApplication in 1.386 seconds (process running for 2.036)

rest api 测试 ok。

img

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
http://localhost:8080/hello

HTTP/1.1 200
Content-Type: text/plain;charset=UTF-8
Content-Length: 32
Date: Mon, 28 Nov 2022 08:31:59 GMT
Keep-Alive: timeout=60
Connection: keep-alive

Hello World from springboot 3.0!

Response code: 200; Time: 175ms (175 ms); Content length: 32 bytes (32 B)
http://localhost:8080/test

HTTP/1.1 200
Content-Type: text/plain;charset=UTF-8
Content-Length: 27
Date: Mon, 28 Nov 2022 08:32:05 GMT
Keep-Alive: timeout=60
Connection: keep-alive

springboot 3.0 访问测试

Response code: 200; Time: 17ms (17 ms); Content length: 19 bytes (19 B)

打包二进制可执行文件需要安装 native-image , 执行 gu install native-image 命令。

打包二进制可执行文件,执行出错:

img

上面报错,因为需要安装 windows docker。

官网下载安装 windows dockerdesktop 完成后。启动 windows dockerdesktop 报错(可能是因为 Windows 11 的默认网络配置被改了,正常不会报错,毕竟是很常用的工具):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
stderr: 
在 Docker.ApiServices.WSL2.WslShortLivedCommandResult.LogAndThrowIfUnexpectedExitCode(String prefix, ILogger log, Int32 expectedExitCode) 位置 C:\workspaces\PR-19568\src\github.com\docker\pinata\win\src\Docker.ApiServices\WSL2\WslCommand.cs:行号 160
在 Docker.Engines.WSL2.WSL2Provisioning.<ProvisionAsync>d__8.MoveNext() 位置 C:\workspaces\PR-19568\src\github.com\docker\pinata\win\src\Docker.Engines\WSL2\WSL2Provisioning.cs:行号 81
--- 引发异常的上一位置中堆栈跟踪的末尾 ---
在 System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
在 System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
在 Docker.Engines.WSL2.LinuxWSL2Engine.<DoStartAsync>d__26.MoveNext() 位置 C:\workspaces\PR-19568\src\github.com\docker\pinata\win\src\Docker.Engines\WSL2\LinuxWSL2Engine.cs:行号 170
--- 引发异常的上一位置中堆栈跟踪的末尾 ---
在 System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
在 System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
在 Docker.ApiServices.StateMachines.TaskExtensions.<WrapAsyncInCancellationException>d__0.MoveNext() 位置 C:\workspaces\PR-19568\src\github.com\docker\pinata\win\src\Docker.ApiServices\StateMachines\TaskExtensions.cs:行号 29
--- 引发异常的上一位置中堆栈跟踪的末尾 ---
在 System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
在 System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
在 Docker.ApiServices.StateMachines.StartTransition.<DoRunAsync>d__5.MoveNext() 位置 C:\workspaces\PR-19568\src\github.com\docker\pinata\win\src\Docker.ApiServices\StateMachines\StartTransition.cs:行号 67
--- 引发异常的上一位置中堆栈跟踪的末尾 ---
在 System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
在 Docker.ApiServices.StateMachines.StartTransition.<DoRunAsync>d__5.MoveNext() 位置 C:\workspaces\PR-19568\src\github.com\docker\pinata\win\src\Docker.ApiServices\StateMachines\StartTransition.cs:行号 92
--- 引发异常的上一位置中堆栈跟踪的末尾 ---
在 System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
在 System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
在 Docker.ApiServices.StateMachines.EngineStateMachine.<StartAsync>d__14.MoveNext() 位置 C:\workspaces\PR-19568\src\github.com\docker\pinata\win\src\Docker.ApiServices\StateMachines\EngineStateMachine.cs:行号 69
--- 引发异常的上一位置中堆栈跟踪的末尾 ---
在 System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
在 System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
在 Docker.Engines.Engines.<StartAsync>d__22.MoveNext() 位置 C:\workspaces\PR-19568\src\github.com\docker\pinata\win\src\Docker.Engines\Engines.cs:行号 106

在 PowerShell(管理员模式)或者 cmd(管理员模式)中执行

1
netsh winsock reset

执行该命令后记得重启!

重启后,Windows 11 下的 dockerdesktop 可以正常启动。

对于没有 vmware 需求,没有虚拟机 vpn 网络需求,仅仅开发 springboot3.0,上面的方式已经可以实现目标。

不过若有 VMware 需求,以及有 VMware 虚拟机共享宿主机 vpn 网络的需求,上面的重置命令慎用,会导致 VMware 里运行的虚拟机使用宿主机 vpn 网络出现问题,网络不通。

并且由于 windows 下的 dockerdesktop 需要打开 hyper-v 或者 WSL 2,一旦打开会影响 VMware 嵌套虚拟化功能,导致 VMware 下虚拟机的嵌套虚拟化功能不可用。

不过也不用担心,只需要 3 步可以恢复:

  1. 卸载 windows dockerdesktop
  2. 设置 - 应用 - 可选功能 - 更多 windows 功能,取消 WSL 2 和 hyper-v 的勾,重启电脑
  3. 卸载 wmware,重新安装 wmware。

这种情况还是在沙盒环境里编译打包原生可执行文件,比如下面的用 Linux 环境。

# Spring Boot 3.0 初步使用(Linux)

上面 windows 跑通的项目源码直接放到 Linux 下,执行,报错:

1
2
[ERROR] Internal error: java.lang.RuntimeException: GraalVM native-image is missing from your system.
[ERROR] Make sure that GRAALVM_HOME environment variable is present.

按报错信息,配置 GRAALVM_HOME 和 安装 GraalVM native-image。

1
2
3
4
5
6
export GRAALVM_HOME 到/etc/bashrc
[hanwei@backendcloud-centos9 ~]$ gu install native-image
Downloading: Component catalog from www.graalvm.org
Processing Component: Native Image
Downloading: Component native-image: Native Image from github.com
Installing new component: Native Image (org.graalvm.native-image, version 22.3.0)

再执行报错:

1
Test configuration file wasn't found.

toggle ‘Skip Tests’ mode,就是在 Linux Idea 的 Maven 窗口,点击跳过测试按钮。

再执行 ok。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
/home/hanwei/sdk/graalvm-ce-java17-22.3.0/bin/java -XX:TieredStopAtLevel=1 -Dspring.output.ansi.enabled=always -Dcom.sun.management.jmxremote -Dspring.jmx.enabled=true -Dspring.liveBeansView.mbeanDomain -Dspring.application.admin.enabled=true -javaagent:/home/hanwei/.local/share/JetBrains/Toolbox/apps/IDEA-U/ch-0/222.4459.24/lib/idea_rt.jar=41343:/home/hanwei/.local/share/JetBrains/Toolbox/apps/IDEA-U/ch-0/222.4459.24/bin -Dfile.encoding=UTF-8 -classpath /home/hanwei/demo/target/classes:/home/hanwei/.m2/repository/org/springframework/boot/spring-boot-starter/3.0.0/spring-boot-starter-3.0.0.jar:/home/hanwei/.m2/repository/org/springframework/boot/spring-boot/3.0.0/spring-boot-3.0.0.jar:/home/hanwei/.m2/repository/org/springframework/spring-context/6.0.2/spring-context-6.0.2.jar:/home/hanwei/.m2/repository/org/springframework/boot/spring-boot-autoconfigure/3.0.0/spring-boot-autoconfigure-3.0.0.jar:/home/hanwei/.m2/repository/org/springframework/boot/spring-boot-starter-logging/3.0.0/spring-boot-starter-logging-3.0.0.jar:/home/hanwei/.m2/repository/ch/qos/logback/logback-classic/1.4.5/logback-classic-1.4.5.jar:/home/hanwei/.m2/repository/ch/qos/logback/logback-core/1.4.5/logback-core-1.4.5.jar:/home/hanwei/.m2/repository/org/apache/logging/log4j/log4j-to-slf4j/2.19.0/log4j-to-slf4j-2.19.0.jar:/home/hanwei/.m2/repository/org/apache/logging/log4j/log4j-api/2.19.0/log4j-api-2.19.0.jar:/home/hanwei/.m2/repository/org/slf4j/jul-to-slf4j/2.0.4/jul-to-slf4j-2.0.4.jar:/home/hanwei/.m2/repository/jakarta/annotation/jakarta.annotation-api/2.1.1/jakarta.annotation-api-2.1.1.jar:/home/hanwei/.m2/repository/org/springframework/spring-core/6.0.2/spring-core-6.0.2.jar:/home/hanwei/.m2/repository/org/springframework/spring-jcl/6.0.2/spring-jcl-6.0.2.jar:/home/hanwei/.m2/repository/org/yaml/snakeyaml/1.33/snakeyaml-1.33.jar:/home/hanwei/.m2/repository/org/slf4j/slf4j-api/2.0.4/slf4j-api-2.0.4.jar:/home/hanwei/.m2/repository/org/springframework/boot/spring-boot-starter-web/3.0.0/spring-boot-starter-web-3.0.0.jar:/home/hanwei/.m2/repository/org/springframework/boot/spring-boot-starter-json/3.0.0/spring-boot-starter-json-3.0.0.jar:/home/hanwei/.m2/repository/com/fasterxml/jackson/core/jackson-databind/2.14.1/jackson-databind-2.14.1.jar:/home/hanwei/.m2/repository/com/fasterxml/jackson/core/jackson-annotations/2.14.1/jackson-annotations-2.14.1.jar:/home/hanwei/.m2/repository/com/fasterxml/jackson/core/jackson-core/2.14.1/jackson-core-2.14.1.jar:/home/hanwei/.m2/repository/com/fasterxml/jackson/datatype/jackson-datatype-jdk8/2.14.1/jackson-datatype-jdk8-2.14.1.jar:/home/hanwei/.m2/repository/com/fasterxml/jackson/datatype/jackson-datatype-jsr310/2.14.1/jackson-datatype-jsr310-2.14.1.jar:/home/hanwei/.m2/repository/com/fasterxml/jackson/module/jackson-module-parameter-names/2.14.1/jackson-module-parameter-names-2.14.1.jar:/home/hanwei/.m2/repository/org/springframework/boot/spring-boot-starter-tomcat/3.0.0/spring-boot-starter-tomcat-3.0.0.jar:/home/hanwei/.m2/repository/org/apache/tomcat/embed/tomcat-embed-core/10.1.1/tomcat-embed-core-10.1.1.jar:/home/hanwei/.m2/repository/org/apache/tomcat/embed/tomcat-embed-el/10.1.1/tomcat-embed-el-10.1.1.jar:/home/hanwei/.m2/repository/org/apache/tomcat/embed/tomcat-embed-websocket/10.1.1/tomcat-embed-websocket-10.1.1.jar:/home/hanwei/.m2/repository/org/springframework/spring-web/6.0.2/spring-web-6.0.2.jar:/home/hanwei/.m2/repository/org/springframework/spring-beans/6.0.2/spring-beans-6.0.2.jar:/home/hanwei/.m2/repository/io/micrometer/micrometer-observation/1.10.2/micrometer-observation-1.10.2.jar:/home/hanwei/.m2/repository/io/micrometer/micrometer-commons/1.10.2/micrometer-commons-1.10.2.jar:/home/hanwei/.m2/repository/org/springframework/spring-webmvc/6.0.2/spring-webmvc-6.0.2.jar:/home/hanwei/.m2/repository/org/springframework/spring-aop/6.0.2/spring-aop-6.0.2.jar:/home/hanwei/.m2/repository/org/springframework/spring-expression/6.0.2/spring-expression-6.0.2.jar com.example.demo.DemoApplication

. ____ _ __ _ _
/\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
\\/ ___)| |_)| | | | | || (_| | ) ) ) )
' |____| .__|_| |_|_| |_\__, | / / / /
=========|_|==============|___/=/_/_/_/
:: Spring Boot :: (v3.0.0)

2022-11-29T00:02:01.348+08:00 INFO 11794 --- [ main] com.example.demo.DemoApplication : Starting DemoApplication using Java 17.0.5 with PID 11794 (/home/hanwei/demo/target/classes started by hanwei in /home/hanwei/demo)
2022-11-29T00:02:01.352+08:00 INFO 11794 --- [ main] com.example.demo.DemoApplication : No active profile set, falling back to 1 default profile: "default"
2022-11-29T00:02:02.011+08:00 INFO 11794 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat initialized with port(s): 8080 (http)
2022-11-29T00:02:02.018+08:00 INFO 11794 --- [ main] o.apache.catalina.core.StandardService : Starting service [Tomcat]
2022-11-29T00:02:02.018+08:00 INFO 11794 --- [ main] o.apache.catalina.core.StandardEngine : Starting Servlet engine: [Apache Tomcat/10.1.1]
2022-11-29T00:02:02.089+08:00 INFO 11794 --- [ main] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring embedded WebApplicationContext
2022-11-29T00:02:02.090+08:00 INFO 11794 --- [ main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 687 ms
2022-11-29T00:02:02.347+08:00 INFO 11794 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat started on port(s): 8080 (http) with context path ''
2022-11-29T00:02:02.350+08:00 INFO 11794 --- [ main] com.example.demo.DemoApplication : Started DemoApplication in 1.335 seconds (process running for 16.893)

可见执行传统 jar 包的启动速度是 1.335 seconds ,下面编译原生二进制文件。点击 Linux Idea 的 Maven 窗口的 build image 按钮。会在项目的 target 目录下(和生成的 jar 包在同一级目录)生成二进制可执行文件。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
/home/hanwei/sdk/graalvm-ce-java17-22.3.0/bin/java -Dmaven.multiModuleProjectDirectory=/home/hanwei/demo -Dmaven.home=/home/hanwei/.m2/wrapper/dists/apache-maven-3.8.6-bin/1ks0nkde5v1pk9vtc31i9d0lcd/apache-maven-3.8.6 -Dclassworlds.conf=/home/hanwei/.m2/wrapper/dists/apache-maven-3.8.6-bin/1ks0nkde5v1pk9vtc31i9d0lcd/apache-maven-3.8.6/bin/m2.conf -Dmaven.ext.class.path=/home/hanwei/.local/share/JetBrains/Toolbox/apps/IDEA-U/ch-0/222.4459.24/plugins/maven/lib/maven-event-listener.jar -javaagent:/home/hanwei/.local/share/JetBrains/Toolbox/apps/IDEA-U/ch-0/222.4459.24/lib/idea_rt.jar=44943:/home/hanwei/.local/share/JetBrains/Toolbox/apps/IDEA-U/ch-0/222.4459.24/bin -Dfile.encoding=UTF-8 -classpath /home/hanwei/.m2/wrapper/dists/apache-maven-3.8.6-bin/1ks0nkde5v1pk9vtc31i9d0lcd/apache-maven-3.8.6/boot/plexus-classworlds.license:/home/hanwei/.m2/wrapper/dists/apache-maven-3.8.6-bin/1ks0nkde5v1pk9vtc31i9d0lcd/apache-maven-3.8.6/boot/plexus-classworlds-2.6.0.jar org.codehaus.classworlds.Launcher -Didea.version=2022.2.4 -DskipTests=true org.graalvm.buildtools:native-maven-plugin:0.9.16:build -P native
[INFO] Scanning for projects...
[INFO]
[INFO] --------------------------< com.example:demo >--------------------------
[INFO] Building demo 0.0.1-SNAPSHOT
[INFO] --------------------------------[ jar ]---------------------------------
[INFO]
[INFO] --- native-maven-plugin:0.9.16:build (default-cli) @ demo ---
[WARNING] 'native:build' goal is deprecated. Use 'native:compile-no-fork' instead.
[INFO] Found GraalVM installation from GRAALVM_HOME variable.
[INFO] [graalvm reachability metadata repository for ch.qos.logback:logback-classic:1.4.5]: Configuration directory not found. Trying latest version.
[INFO] [graalvm reachability metadata repository for ch.qos.logback:logback-classic:1.4.5]: Configuration directory is ch.qos.logback/logback-classic/1.4.1
[INFO] [graalvm reachability metadata repository for org.apache.tomcat.embed:tomcat-embed-core:10.1.1]: Configuration directory not found. Trying latest version.
[INFO] [graalvm reachability metadata repository for org.apache.tomcat.embed:tomcat-embed-core:10.1.1]: Configuration directory is org.apache.tomcat.embed/tomcat-embed-core/10.0.20
[INFO] Executing: /home/hanwei/sdk/graalvm-ce-java17-22.3.0/bin/native-image -cp /home/hanwei/demo/target/classes:/home/hanwei/.m2/repository/org/slf4j/jul-to-slf4j/2.0.4/jul-to-slf4j-2.0.4.jar:/home/hanwei/.m2/repository/org/springframework/spring-web/6.0.2/spring-web-6.0.2.jar:/home/hanwei/.m2/repository/ch/qos/logback/logback-core/1.4.5/logback-core-1.4.5.jar:/home/hanwei/.m2/repository/jakarta/annotation/jakarta.annotation-api/2.1.1/jakarta.annotation-api-2.1.1.jar:/home/hanwei/.m2/repository/com/fasterxml/jackson/core/jackson-annotations/2.14.1/jackson-annotations-2.14.1.jar:/home/hanwei/.m2/repository/org/springframework/boot/spring-boot-starter-json/3.0.0/spring-boot-starter-json-3.0.0.jar:/home/hanwei/.m2/repository/org/springframework/spring-core/6.0.2/spring-core-6.0.2.jar:/home/hanwei/.m2/repository/com/fasterxml/jackson/module/jackson-module-parameter-names/2.14.1/jackson-module-parameter-names-2.14.1.jar:/home/hanwei/.m2/repository/org/apache/tomcat/embed/tomcat-embed-websocket/10.1.1/tomcat-embed-websocket-10.1.1.jar:/home/hanwei/.m2/repository/ch/qos/logback/logback-classic/1.4.5/logback-classic-1.4.5.jar:/home/hanwei/.m2/repository/org/springframework/spring-jcl/6.0.2/spring-jcl-6.0.2.jar:/home/hanwei/.m2/repository/org/springframework/boot/spring-boot-starter-web/3.0.0/spring-boot-starter-web-3.0.0.jar:/home/hanwei/.m2/repository/org/springframework/boot/spring-boot-autoconfigure/3.0.0/spring-boot-autoconfigure-3.0.0.jar:/home/hanwei/.m2/repository/org/springframework/spring-beans/6.0.2/spring-beans-6.0.2.jar:/home/hanwei/.m2/repository/org/springframework/boot/spring-boot-starter-tomcat/3.0.0/spring-boot-starter-tomcat-3.0.0.jar:/home/hanwei/.m2/repository/com/fasterxml/jackson/datatype/jackson-datatype-jsr310/2.14.1/jackson-datatype-jsr310-2.14.1.jar:/home/hanwei/.m2/repository/org/apache/tomcat/embed/tomcat-embed-el/10.1.1/tomcat-embed-el-10.1.1.jar:/home/hanwei/.m2/repository/com/fasterxml/jackson/core/jackson-core/2.14.1/jackson-core-2.14.1.jar:/home/hanwei/.m2/repository/org/apache/logging/log4j/log4j-api/2.19.0/log4j-api-2.19.0.jar:/home/hanwei/.m2/repository/org/springframework/spring-expression/6.0.2/spring-expression-6.0.2.jar:/home/hanwei/.m2/repository/org/springframework/spring-webmvc/6.0.2/spring-webmvc-6.0.2.jar:/home/hanwei/.m2/repository/org/springframework/boot/spring-boot/3.0.0/spring-boot-3.0.0.jar:/home/hanwei/.m2/repository/org/apache/tomcat/embed/tomcat-embed-core/10.1.1/tomcat-embed-core-10.1.1.jar:/home/hanwei/.m2/repository/org/springframework/spring-aop/6.0.2/spring-aop-6.0.2.jar:/home/hanwei/.m2/repository/org/apache/logging/log4j/log4j-to-slf4j/2.19.0/log4j-to-slf4j-2.19.0.jar:/home/hanwei/.m2/repository/org/springframework/boot/spring-boot-starter/3.0.0/spring-boot-starter-3.0.0.jar:/home/hanwei/.m2/repository/org/springframework/boot/spring-boot-starter-logging/3.0.0/spring-boot-starter-logging-3.0.0.jar:/home/hanwei/.m2/repository/org/slf4j/slf4j-api/2.0.4/slf4j-api-2.0.4.jar:/home/hanwei/.m2/repository/org/springframework/spring-context/6.0.2/spring-context-6.0.2.jar:/home/hanwei/.m2/repository/io/micrometer/micrometer-observation/1.10.2/micrometer-observation-1.10.2.jar:/home/hanwei/.m2/repository/org/yaml/snakeyaml/1.33/snakeyaml-1.33.jar:/home/hanwei/.m2/repository/com/fasterxml/jackson/core/jackson-databind/2.14.1/jackson-databind-2.14.1.jar:/home/hanwei/.m2/repository/com/fasterxml/jackson/datatype/jackson-datatype-jdk8/2.14.1/jackson-datatype-jdk8-2.14.1.jar:/home/hanwei/.m2/repository/io/micrometer/micrometer-commons/1.10.2/micrometer-commons-1.10.2.jar --no-fallback -H:Path=/home/hanwei/demo/target -H:Name=demo -H:ConfigurationFileDirectories=/home/hanwei/demo/target/graalvm-reachability-metadata/39f9c4cd5765941e97b499c39e24353f8a36ebd3/org.apache.tomcat.embed/tomcat-embed-core/10.0.20,/home/hanwei/demo/target/graalvm-reachability-metadata/39f9c4cd5765941e97b499c39e24353f8a36ebd3/ch.qos.logback/logback-classic/1.4.1
========================================================================================================================
GraalVM Native Image: Generating 'demo' (executable)...
========================================================================================================================
[1/7] Initializing... (6.4s @ 0.18GB)
Version info: 'GraalVM 22.3.0 Java 17 CE'
Java version info: '17.0.5+8-jvmci-22.3-b08'
C compiler: gcc (redhat, x86_64, 11.3.1)
Garbage collector: Serial GC
1 user-specific feature(s)
- org.springframework.aot.nativex.feature.PreComputeFieldFeature
The bundle named: org.apache.el.Messages, has not been found. If the bundle is part of a module, verify the bundle name is a fully qualified class name. Otherwise verify the bundle path is accessible in the classpath.
Field org.springframework.core.NativeDetector#imageCode set to true at build time
Field org.apache.commons.logging.LogAdapter#log4jSpiPresent set to true at build time
Field org.apache.commons.logging.LogAdapter#log4jSlf4jProviderPresent set to true at build time
Field org.apache.commons.logging.LogAdapter#slf4jSpiPresent set to true at build time
Field org.apache.commons.logging.LogAdapter#slf4jApiPresent set to true at build time
Field org.springframework.format.support.DefaultFormattingConversionService#jsr354Present set to false at build time
Field org.springframework.core.KotlinDetector#kotlinPresent set to false at build time
Field org.springframework.core.KotlinDetector#kotlinReflectPresent set to false at build time
Field org.springframework.cglib.core.AbstractClassGenerator#imageCode set to true at build time
Field org.springframework.boot.logging.java.JavaLoggingSystem$Factory#PRESENT set to true at build time
Field org.springframework.boot.logging.log4j2.Log4J2LoggingSystem$Factory#PRESENT set to false at build time
Field org.springframework.boot.logging.logback.LogbackLoggingSystem$Factory#PRESENT set to true at build time
Field org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport#romePresent set to false at build time
Field org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport#jaxb2Present set to false at build time
Field org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport#jackson2Present set to true at build time
Field org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport#jackson2XmlPresent set to false at build time
Field org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport#jackson2SmilePresent set to false at build time
Field org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport#jackson2CborPresent set to false at build time
Field org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport#gsonPresent set to false at build time
Field org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport#jsonbPresent set to false at build time
Field org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport#kotlinSerializationCborPresent set to false at build time
Field org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport#kotlinSerializationJsonPresent set to false at build time
Field org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport#kotlinSerializationProtobufPresent set to false at build time
Field org.springframework.web.servlet.view.InternalResourceViewResolver#jstlPresent set to false at build time
Field org.springframework.web.context.support.StandardServletEnvironment#jndiPresent set to true at build time
Field org.springframework.web.context.support.WebApplicationContextUtils#jsfPresent set to false at build time
Field org.springframework.web.context.request.RequestContextHolder#jsfPresent set to false at build time
Field org.springframework.context.event.ApplicationListenerMethodAdapter#reactiveStreamsPresent set to false at build time
Field org.springframework.boot.logging.logback.LogbackLoggingSystemProperties#JBOSS_LOGGING_PRESENT set to false at build time
Field org.springframework.http.converter.support.AllEncompassingFormHttpMessageConverter#jaxb2Present set to false at build time
Field org.springframework.http.converter.support.AllEncompassingFormHttpMessageConverter#jackson2Present set to true at build time
Field org.springframework.http.converter.support.AllEncompassingFormHttpMessageConverter#jackson2XmlPresent set to false at build time
Field org.springframework.http.converter.support.AllEncompassingFormHttpMessageConverter#jackson2SmilePresent set to false at build time
Field org.springframework.http.converter.support.AllEncompassingFormHttpMessageConverter#gsonPresent set to false at build time
Field org.springframework.http.converter.support.AllEncompassingFormHttpMessageConverter#jsonbPresent set to false at build time
Field org.springframework.http.converter.support.AllEncompassingFormHttpMessageConverter#kotlinSerializationCborPresent set to false at build time
Field org.springframework.http.converter.support.AllEncompassingFormHttpMessageConverter#kotlinSerializationJsonPresent set to false at build time
Field org.springframework.http.converter.support.AllEncompassingFormHttpMessageConverter#kotlinSerializationProtobufPresent set to false at build time
Field org.springframework.boot.autoconfigure.web.format.WebConversionService#JSR_354_PRESENT set to false at build time
Field org.springframework.web.client.RestTemplate#romePresent set to false at build time
Field org.springframework.web.client.RestTemplate#jaxb2Present set to false at build time
Field org.springframework.web.client.RestTemplate#jackson2Present set to true at build time
Field org.springframework.web.client.RestTemplate#jackson2XmlPresent set to false at build time
Field org.springframework.web.client.RestTemplate#jackson2SmilePresent set to false at build time
Field org.springframework.web.client.RestTemplate#jackson2CborPresent set to false at build time
Field org.springframework.web.client.RestTemplate#gsonPresent set to false at build time
Field org.springframework.web.client.RestTemplate#jsonbPresent set to false at build time
Field org.springframework.web.client.RestTemplate#kotlinSerializationCborPresent set to false at build time
Field org.springframework.web.client.RestTemplate#kotlinSerializationJsonPresent set to false at build time
Field org.springframework.web.client.RestTemplate#kotlinSerializationProtobufPresent set to false at build time
Field org.springframework.core.ReactiveAdapterRegistry#reactorPresent set to false at build time
Field org.springframework.core.ReactiveAdapterRegistry#rxjava3Present set to false at build time
Field org.springframework.core.ReactiveAdapterRegistry#kotlinCoroutinesPresent set to false at build time
Field org.springframework.core.ReactiveAdapterRegistry#mutinyPresent set to false at build time
SLF4J: No SLF4J providers were found.
SLF4J: Defaulting to no-operation (NOP) logger implementation
SLF4J: See https://www.slf4j.org/codes.html#noProviders for further details.
Field org.springframework.web.servlet.mvc.method.annotation.ReactiveTypeHandler#isContextPropagationPresent set to false at build time
Field org.springframework.web.servlet.support.RequestContext#jstlPresent set to false at build time
[2/7] Performing analysis... [*********] (54.5s @ 1.28GB)
15,278 (92.35%) of 16,544 classes reachable
24,932 (67.63%) of 36,867 fields reachable
73,534 (62.25%) of 118,132 methods reachable
780 classes, 163 fields, and 3,506 methods registered for reflection
64 classes, 70 fields, and 55 methods registered for JNI access
4 native libraries: dl, pthread, rt, z
[3/7] Building universe... (5.2s @ 4.12GB)
[4/7] Parsing methods... [**] (4.2s @ 4.35GB)
[5/7] Inlining methods... [***] (1.9s @ 2.82GB)
[6/7] Compiling methods... [*****] (27.8s @ 3.46GB)
[7/7] Creating image... (6.1s @ 1.15GB)
32.83MB (49.82%) for code area: 48,151 compilation units
32.75MB (49.70%) for image heap: 354,531 objects and 320 resources
324.99KB ( 0.48%) for other data
65.90MB in total
------------------------------------------------------------------------------------------------------------------------
Top 10 packages in code area: Top 10 object types in image heap:
1.63MB sun.security.ssl 7.21MB byte[] for code metadata
1.04MB java.util 3.88MB byte[] for embedded resources
832.55KB java.lang.invoke 3.63MB java.lang.Class
718.00KB com.sun.crypto.provider 3.39MB java.lang.String
541.00KB org.apache.catalina.core 2.80MB byte[] for java.lang.String
499.59KB org.apache.tomcat.util.net 2.79MB byte[] for general heap data
490.49KB org.apache.coyote.http2 1.28MB com.oracle.svm.core.hub.DynamicHubCompanion
472.53KB java.lang 815.22KB byte[] for reflection metadata
461.63KB sun.security.x509 659.44KB java.lang.String[]
459.52KB java.util.concurrent 648.80KB java.util.HashMap$Node
25.43MB for 637 more packages 5.47MB for 3070 more object types
------------------------------------------------------------------------------------------------------------------------
9.1s (7.9% of total time) in 37 GCs | Peak RSS: 6.43GB | CPU load: 4.46
------------------------------------------------------------------------------------------------------------------------
Produced artifacts:
/home/hanwei/demo/target/demo (executable)
/home/hanwei/demo/target/demo.build_artifacts.txt (txt)
========================================================================================================================
Finished generating 'demo' in 1m 53s.
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 01:55 min
[INFO] Finished at: 2022-11-28T23:55:32+08:00
[INFO] ------------------------------------------------------------------------

Process finished with exit code 0

执行二进制可执行文件,启动速度只有 0.052 seconds 。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
[hanwei@backendcloud-centos9 ~]$ cd demo/target/
[hanwei@backendcloud-centos9 target]$ ls
classes demo demo-0.0.1-SNAPSHOT.jar demo-0.0.1-SNAPSHOT.jar.original demo.build_artifacts.txt generated-sources generated-test-sources graalvm-reachability-metadata maven-archiver maven-status spring-aot surefire-reports test-classes
[hanwei@backendcloud-centos9 target]$ ./demo

. ____ _ __ _ _
/\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
\\/ ___)| |_)| | | | | || (_| | ) ) ) )
' |____| .__|_| |_|_| |_\__, | / / / /
=========|_|==============|___/=/_/_/_/
:: Spring Boot :: (v3.0.0)

2022-11-29T00:03:59.026+08:00 INFO 12061 --- [ main] com.example.demo.DemoApplication : Starting AOT-processed DemoApplication using Java 17.0.5 with PID 12061 (/home/hanwei/demo/target/demo started by hanwei in /home/hanwei/demo/target)
2022-11-29T00:03:59.026+08:00 INFO 12061 --- [ main] com.example.demo.DemoApplication : No active profile set, falling back to 1 default profile: "default"
2022-11-29T00:03:59.040+08:00 INFO 12061 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat initialized with port(s): 8080 (http)
2022-11-29T00:03:59.040+08:00 INFO 12061 --- [ main] o.apache.catalina.core.StandardService : Starting service [Tomcat]
2022-11-29T00:03:59.040+08:00 INFO 12061 --- [ main] o.apache.catalina.core.StandardEngine : Starting Servlet engine: [Apache Tomcat/10.1.1]
2022-11-29T00:03:59.044+08:00 INFO 12061 --- [ main] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring embedded WebApplicationContext
2022-11-29T00:03:59.044+08:00 INFO 12061 --- [ main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 18 ms
2022-11-29T00:03:59.068+08:00 INFO 12061 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat started on port(s): 8080 (http) with context path ''
2022-11-29T00:03:59.068+08:00 INFO 12061 --- [ main] com.example.demo.DemoApplication : Started DemoApplication in 0.052 seconds (process running for 0.056)
[hanwei@backendcloud-centos9 target]$ ll -h
total 84M
drwxr-xr-x. 5 hanwei hanwei 74 Nov 28 23:15 classes
-rwxr-xr-x. 1 hanwei hanwei 66M Nov 28 23:55 demo
-rw-r--r--. 1 hanwei hanwei 18M Nov 28 23:49 demo-0.0.1-SNAPSHOT.jar
-rw-r--r--. 1 hanwei hanwei 119K Nov 28 23:49 demo-0.0.1-SNAPSHOT.jar.original
-rw-r--r--. 1 hanwei hanwei 19 Nov 28 23:55 demo.build_artifacts.txt
drwxr-xr-x. 3 hanwei hanwei 25 Nov 28 22:59 generated-sources
drwxr-xr-x. 3 hanwei hanwei 30 Nov 28 22:59 generated-test-sources
drwxr-xr-x. 4 hanwei hanwei 101 Nov 28 23:42 graalvm-reachability-metadata
drwxr-xr-x. 2 hanwei hanwei 28 Nov 28 22:59 maven-archiver
drwxr-xr-x. 3 hanwei hanwei 35 Nov 28 22:59 maven-status
drwxr-xr-x. 3 hanwei hanwei 18 Nov 28 22:59 spring-aot
drwxr-xr-x. 2 hanwei hanwei 153 Nov 28 23:03 surefire-reports
drwxr-xr-x. 3 hanwei hanwei 17 Nov 28 22:59 test-classes

对比两种打包方式:jar 包和原生可执行文件,jar 包 18 兆,原生可执行文件因为可以不依赖 java 运行环境而直接运行,所以体积大些,60 兆。

上面是通过 Linux Idea 的 Maven 窗口执行的。也可以通过命令行执行 mvn 命令生成原生二进制文件。

1
2
3
4
5
6
7
8
9
10
11
12
[hanwei@backendcloud-centos9 target]$ which mvn
~/.local/bin/mvn
[hanwei@backendcloud-centos9 target]$ ll ~/.local/bin/mvn
lrwxrwxrwx. 1 hanwei hanwei 107 Nov 28 22:57 /home/hanwei/.local/bin/mvn -> /home/hanwei/.m2/wrapper/dists/apache-maven-3.8.6-bin/1ks0nkde5v1pk9vtc31i9d0lcd/apache-maven-3.8.6/bin/mvn
# 到feature-native目录下
[hanwei@backendcloud-centos9 demo]$ cd ..
[hanwei@backendcloud-centos9 demo]$ mvn clean
# 打包
[hanwei@backendcloud-centos9 demo]$ mvn package -Pnative
# 可执行文件
[hanwei@backendcloud-centos9 demo]$ mvn native:compile-no-fork
# 到target目录下启动可执行文件

从上面的执行效果对比看出,云原生时代的 Spring Boot 3.0: GraalVM 编译的二进制可执行文件,启动速度相对于传统 jar 包提升近 30 倍(1.335 seconds -> 0.052 seconds)。

# 欢迎订阅微信公众号 “InterviewCoder” !

# 关于我

Brath 是一个热爱技术的 Java 程序猿,公众号「InterviewCoder」定期分享有趣有料的精品原创文章!

InterviewCoder

非常感谢各位人才能看到这里,原创不易,文章如果有帮助可以关注、点赞、分享或评论,这都是对我的莫大支持!

评论