CodeRoadMap
首页路线题库资源库文章社区
CodeRoadMap

程序员的学习成长路线图。内容免费开放,登录后可同步路线图与课时进度。

由 程序员柏风 独立维护 · 关于作者

学习

  • 路线图
  • 课程
  • 面试题
  • 文章
  • 我

更多

  • 资源
  • 社区
  • 关于作者
  • 内容说明

© 2026 CodeRoadMap

津ICP备2026012044号-1·津公网安备12011002026155号·coderoadmap@126.com
Java 进阶/课时/Quarkus 入门
RawBlame
课时目录12 节

Java 进阶

  1. 01Java 进阶概览
  2. 02枚举与模式
  3. 03Set/Queue/Stack
  4. 04OOP 进阶
  5. 05方法链与绑定
  6. 06Record 与不可变
  7. 07模块系统
  8. 08并发进阶
  9. 09依赖注入概念
  10. 10Java Web 框架
  11. 11Quarkus 入门
  12. 12综合练习

Quarkus 入门

云原生 Java、Native 编译概念。

35 分钟

Quarkus 入门

这一课你将能做到

  1. 创建并运行一个最小 Quarkus REST 项目,理解 JAX-RS 注解与开发态热重载的工作方式
  2. 说出 JVM 模式与 Native 模式的取舍,解释 Native Image 为什么启动快、代价是什么
  3. 把 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 响应体
}

访问 http://localhost:8080/orders/1,返回 {"id":1,"status":"PAID"}。改动 statusOf 的实现,保存后刷新页面即见新结果——热重载覆盖普通类改动。

步骤 3:配置与打包

src/main/resources/application.properties:

quarkus.http.port=8080
order.greeting=hello

打包与运行:

./mvnw package                       # 产出普通 jar(默认 JVM 模式)
java -jar target/quarkus-app/quarkus-run.jar

可选:装好 GraalVM 后构建 Native(构建慢属正常,分钟级):

./mvnw package -Dnative
./target/hello-quarkus-1.0.0-SNAPSHOT-runner   # 直接是原生可执行文件

启动日志里能看到毫秒级 started in,对比 jar 模式的启动时间,这就是 Native 的直观证据。

步骤 4:跑一次开发态测试(选做)

Quarkus 项目自带测试骨架 src/test/java,./mvnw test 即可;quarkus:dev 下还提供连续测试模式。测试不依赖容器预启动,启动成本同样受益于 Quarkus 的快速引导。

讲清楚要点

  1. Quarkus 的核心思路是构建期偏移:把 Spring 在运行期做的事(扫描 Bean、生成代理、解析配置、建立路由表)尽量挪到构建期,启动时只做装配——启动快、内存低、Native 可行,三个收益同源。
  2. JAX-RS 是标准 API:@Path/@GET/@Produces 属于 Jakarta RESTful Web Services 规范,Quarkus 用 RESTEasy Reactive 实现。注解与 Spring MVC 不同,HTTP 语义完全一致,迁移是「换注解」而不是「换思维」。
  3. CDI 是标准 DI:@ApplicationScoped ≈ Spring singleton Bean,@Inject ≈ @Autowired;第 9 课的构造器注入在这里同样是默认推荐,单构造器可省略 @Inject。
  4. JVM vs Native 取舍:JVM 模式构建快、峰值性能高(JIT 充分预热后),适合长跑服务;Native 冷启动毫秒级、内存小、无 JIT 预热,适合 Serverless/缩容到零。多数常规后端服务,JVM 模式就够。
  5. Native 的封闭世界假设:构建时必须确定所有可达代码,运行期反射、动态代理、动态类加载受限——这就是 Spring 应用做 Native 需要 AOT 处理引擎补元数据的原因,Quarkus 靠扩展在构建期消化掉了大部分需求。
  6. 选型务实:国内就业与站内项目主线仍是 Spring Boot;Quarkus 定位是「知道原理 + 需要时能评估 POC」,不必为学而学替换存量技术栈。

你可能会懵的地方

  • AOT 和 JIT 到底差在哪? JIT(即时编译):运行期统计热点把字节码编译成机器码,峰值性能高但要预热,启动慢;AOT(提前编译):构建期直接生成机器码,启动即峰值、无预热,但无法做基于运行时画像的激进优化,且放弃部分动态能力。
  • Quarkus 的 dev 模式为什么这么快? 构建期已完成大部分静态工作,dev 模式只对改动的类做局部重建与热替换;配合 live reload 通道,改动到生效是毫秒级。
  • Spring 项目能直接上 Native 吗? Spring Boot 3 起官方支持 GraalVM Native(Spring AOT),但要求依赖与配置对反射友好、构建时间显著变长、部分库需额外元数据;存量项目是「评估后局部试点」,不是一键切换。
  • Quarkus 和 Micronaut 是竞品吗? 同属构建期优化的现代框架,Quarkus 主打 GraalVM/云原生生态整合(Kubernetes、Dev Services),Micronaut 主打编译期 DI 注解处理器。思路相似,生态侧重不同。
  • record 能在 Quarkus 里当响应体吗? 能,RESTEasy Reactive + Jackson 原生支持 record 序列化,与 Spring Boot 2.6+ 行为一致——标准与规范的价值就在这类互通上。

错法对照

错法问题正解
用 Spring 注解(@RestController)写 Quarkus注解不存在,编译错JAX-RS:@Path + @GET + @Produces
在运行期大量用反射/Class.forNameNative 下不可达,直接失效构建期注册或改用扩展提供的机制
拿 Native 对比「冷启动」就说 JVM 慢JVM 长跑峰值未必输对比要区分冷启动与稳态吞吐
给 Quarkus 配 Spring 的 application.yml 语义键前缀与自动配置不同按 Quarkus 指南查对应配置键
把 quarkus:dev 当生产模式dev 模式带热重载与调试端口生产用 package 产物 + 对应 profile

卡点急救

  1. quarkus:dev 端口冲突:默认 8080 被占。改 application.properties 里 quarkus.http.port=8081,或启动参数 -Dquarkus.http.port=8081。
  2. Native 构建失败提示缺少工具链:确认 GraalVM 已安装且 native-image 可用(gu install native-image 老版本;新版本自带);Windows 还需要 Visual Studio Build Tools 的 C++ 工具链。
  3. 改了代码没生效:dev 模式只监听 src/main 下的标准位置;确认文件在正确目录、保存触发编译无报错(看终端日志 reload 输出)。

面试常问

  • Native Image 为什么启动快?代价是什么? 可背版:构建期(AOT)就把应用与运行时编译成原生机器码,启动无需类加载、解释执行与 JIT 预热,内存中也没有 JIT 编译器本身,因此冷启动毫秒级、内存占用低。代价:构建慢、依赖封闭世界假设(反射/动态代理需构建期注册)、峰值优化弱于充分预热的 JIT。
  • Quarkus 与 Spring Boot 怎么选? 团队与生态已标准化 Spring、服务长跑且无极致冷启动诉求 → Spring Boot;Serverless、K8s 大规模弹性缩容、边缘函数、内存成本敏感 → 评估 Quarkus(尤其 Native)。答法要点是「按场景匹配启动/内存/生态三个变量」,而不是站队。
  • Quarkus 快的本质原因是什么? 构建期偏移:把 Bean 发现、代理生成、路由构建、配置解析从运行期搬到构建期,运行期只做最少装配;叠加 GraalVM Native 后连 JVM 引导都省了。一句话:把「运行时的智能」换成「构建期的确定性」。

自测三问

  1. @Path + @GET 属于哪个规范?Spring 的对应注解是什么?
  2. 为什么说 Native 模式下「反射要用得小心」?封闭世界假设是什么意思?
  3. 同一个服务,什么指标变化时你会从 JVM 模式切到 Native?

小结一句话

Quarkus = 标准 CDI + JAX-RS + 构建期偏移 + 可选 Native;它是云原生 Java 的另一个答案,学它是为了看清 Spring 的成本结构。

延伸

  • Quarkus 官方 Getting Started 指南
  • Quarkus 官方文档:Native 指南
  • 下一课:综合练习
加载本节练习…
← 上一课Java Web 框架下一课 →综合练习