Quarkus 入门
云原生 Java、Native 编译概念。
Quarkus 入门
这一课你将能做到
- 创建并运行一个最小 Quarkus REST 项目,理解 JAX-RS 注解与开发态热重载的工作方式
- 说出 JVM 模式与 Native 模式的取舍,解释 Native Image 为什么启动快、代价是什么
- 把 Spring 的概念(@RestController、@Autowired、application.properties)一一映射到 Quarkus 对应物
为什么要学
Quarkus 自称「Supersonic Subatomic Java」:开发态毫秒级热重载,生产态可选 GraalVM Native Image 把应用编译成原生可执行文件,冷启动从几秒压到几十毫秒、内存占用大幅下降——这正是 Serverless、大规模容器调度、按量付费场景最关心的指标。
对 Spring 用户的价值不在「换框架」,而在「看懂另一个答案」:Quarkus 把 DI、配置、HTTP 层的处理从运行期挪到构建期(AOT 思路),对照之后你会更清楚 Spring 的反射魔法究竟花了什么成本。面试聊「AOT vs JIT」「云原生 Java」时,这就是你的差异化谈资。
先建立图像
传统 JVM 模式 Native 模式
┌──────────────────────────┐ ┌──────────────────────────┐
│ OS → JVM → 字节码 │ │ OS → 原生可执行文件 │
│ 启动:类加载+解释+JIT 预热 │ │ 启动:直接机器码执行 │
│ 冷启动:秒级 │ │ 冷启动:几十毫秒 │
│ 峰值性能:JIT 优化后最高 │ │ 峰值:略低于充分 JIT 预热 │
│ 构建:快 │ │ 构建:慢(分钟级)+需 GraalVM │
└──────────────────────────┘ └──────────────────────────┘
适合常规部署、长跑服务 适合 Serverless/缩容到零/边缘
跟着做
步骤 1:创建项目并进入开发模式
用 Quarkus CLI 或 code.quarkus.io 生成:
quarkus create app com.example:hello-quarkus --extension='rest-jackson'
cd hello-quarkus
./mvnw quarkus:dev
没有 CLI 时,打开 code.quarkus.io 选 REST Jackson 扩展下载 zip,解压后同样执行 ./mvnw quarkus:dev(Windows 用 mvnw.cmd)。开发模式下改代码保存即生效,无需重启——体验与 Spring Boot DevTools 类似但更彻底。
步骤 2:写一个 REST 资源 + CDI 服务
src/main/java/com/example/OrderService.java:
package com.example;
import jakarta.enterprise.context.ApplicationScoped;
@ApplicationScoped // CDI 的单例作用域,对应 Spring 的 @Service + singleton
public class OrderService {
public String statusOf(long id) {
return id % 2 == 0 ? "SHIPPED" : "PAID";
}
}
src/main/java/com/example/OrderResource.java:
package com.example;
import jakarta.inject.Inject;
import jakarta.ws.rs.GET;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.PathParam;
import jakarta.ws.rs.Produces;
import jakarta.ws.rs.core.MediaType;
@Path("/orders") // JAX-RS:类级路径
public class OrderResource {
private final OrderService service;
public OrderResource(OrderService service) { // 构造器注入:单构造器可省 @Inject
this.service = service;
}
@GET
@Path("/{id}") // 方法级路径
@Produces(MediaType.APPLICATION_JSON)
public OrderView get(@PathParam("id") long id) {
return new OrderView(id, service.statusOf(id));
}
public record OrderView(long id, String status) {} // record 直接做 JSON 响应体
}