# 安装JDK21和GraalVM
sudo apt install -y software-properties-common
sudo add-apt-repository ppa:openjdk-r/ppa
sudo apt install openjdk-21-jdk
# 下载GraalVM
wget https://github.com/graalvm/graalvm-ce-builds/releases/download/vm-23.3.0/graalvm-ce-java21-linux-amd64-23.3.0.tar.gz
tar -xzf graalvm-ce-java21-linux-amd64-23.3.0.tar.gz
sudo mv graalvm-ce-java21-23.3.0 /opt/graalvm
玄学提示:GraalVM的
native-image
是"原生镜像生成器",能把你Java代码变成"二进制火箭"!
<parent>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-parentartifactId>
<version>3.2.0version>
parent>
<properties>
<java.version>21java.version>
<maven.compiler.release>21maven.compiler.release>
properties>
陷阱警告:Spring Boot 3.2已迁移到Jakarta EE 10,所有
javax
包都要换成jakarta
!
// 用记录器替代POJO:像用"压缩包"打包数据
public record UserRecord(String id, String name, int age) implements Serializable {}
@RestController
public class UserController {
@GetMapping("/user/{id}")
public UserRecord getUser(@PathVariable String id) {
return new UserRecord(id, "孙悟空", 1000); // 代码减半,可读性翻倍
}
}
JDK21黑话:
record
就像"数据压缩包",自动生成equals
/hashCode
/toString
!
// 模式匹配:像用"咒语"识别类型
public void processRequest(Object request) {
if (request instanceof UserRecord user) {
System.out.println("用户ID:" + user.id());
} else if (request instanceof OrderRecord order) {
System.out.println("订单金额:" + order.amount());
}
}
代码玄学:
instanceof
后直接赋值,省去90%的类型转换代码!
// 使用Jakarta的新注解
@Path("/api/v1")
public class MyResource {
@GET
@Produces(MediaType.APPLICATION_JSON)
public UserRecord get() {
return new UserRecord("1", "Java21", 21);
}
}
迁移心法:
javax.servlet
→jakarta.servlet
,@RestController
包路径也变了!
<plugin>
<groupId>org.graalvm.buildtoolsgroupId>
<artifactId>native-maven-pluginartifactId>
<version>0.9.26version>
<configuration>
<enableUrlProtocols>http,httpsenableUrlProtocols>
<noServer>truenoServer>
configuration>
plugin>
# 构建命令:像用"魔法咒语"生成镜像
mvn clean package -Pnative -Dquarkus.native.container-build=true
GraalVM玄学:
-Dquarkus.native.container-build
是"容器化构建咒语",在Docker里跑得更快!
# 传统JVM启动时间
time java -jar app.jar
# 输出:1.2秒(像乌龟)
# 原生镜像启动时间
time ./app
# 输出:0.2秒(像猎豹)
性能黑话:原生镜像的"冷启动"时间能减少90%!
// 使用结构化并发:像用"乐高"搭建线程
public void process() {
try (var scope = new StructuredTaskScope.ShutdownOnFailure()) {
var task1 = scope.fork(() -> {
// 子任务1
return "任务1完成";
});
var task2 = scope.fork(() -> {
// 子任务2
return "任务2完成";
});
scope.join(); // 等待所有任务完成
System.out.println(task1.get());
System.out.println(task2.get());
} catch (InterruptedException | ExecutionException e) {
// 异常处理
}
}
JDK21黑话:
StructuredTaskScope
是"线程管理器",能自动处理子任务的生命周期!
// 使用虚拟线程:像用"水龙头"开线程
public void handleRequest() {
var thread = Thread.startVirtualThread(() -> {
// 处理请求
System.out.println("虚拟线程ID:" + Thread.currentThread().getId());
});
thread.start();
}
线程玄学:虚拟线程的"开销"是传统线程的1/1000!
// 使用Spring WebFlux + 原生镜像
@RestController
public class ReactiveController {
@GetMapping("/reactive")
public Mono<UserRecord> getReactive() {
return Mono.just(new UserRecord("1", "Reactive", 21))
.delayElement(Duration.ofSeconds(1));
}
}
响应式黑话:
Mono
和Flux
是"异步数据流",搭配原生镜像能实现"秒级响应"!
// 使用JDK21的内存诊断工具
public class MemoryOptimizer {
public static void main(String[] args) {
// 启动参数:-XX:+UnlockDiagnosticVMOptions -XX:+PrintNMTStatistics
// 输出内存分配详细报告
}
}
内存玄学:
PrintNMTStatistics
是"内存CT扫描仪",能揪出内存泄漏的"凶手"!
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-webartifactId>
<exclusions>
<exclusion>
<groupId>org.springframeworkgroupId>
<artifactId>spring-webartifactId>
exclusion>
exclusions>
dependency>
依赖黑话:“排除依赖"就像"清理房间”,避免版本冲突!
# 构建时添加诊断参数
mvn package -Pnative -agentlib:native-image-agent=config-output-dir=./config
GraalVM玄学:
config-output-dir
会生成"缺失类/方法"的清单,帮你定位问题!
(突然掏出神秘火箭筒)现在你已经掌握了: