自上一章了解Quarkus的核心特性后,让我们动手搭建开发环境并创建第一个Quarkus项目。Quarkus提供了多种便捷的项目创建方式,适合不同场景和开发者偏好。
环境准备
开始Quarkus开发前,需要确保系统满足以下基本要求:
JDK:推荐使用JDK 17或更高版本(LTS版本),这是运行Quarkus应用的基石。
构建工具:Quarkus支持Maven和Gradle,推荐使用Apache Maven 3.6.2+。
开发工具:任何Java IDE均可,IntelliJ IDEA和VS Code都有很好的Quarkus插件支持。
可选组件:
Docker:用于容器化部署
GraalVM:如需构建原生镜像
# 检查环境是否符合要求
java -version
mvn -v
创建Quarkus项目
Quarkus提供多种项目创建方式,以下是三种最常用的方法:
1. 使用Maven命令创建
这是最直接的方式,适合习惯命令行的开发者:
mvn io.quarkus.platform:quarkus-maven-plugin:3.10.1:create \
-DprojectGroupId=com.cxl \
-DprojectArtifactId=my-quarkus-app \
-Dextensions="resteasy-reactive,io.quarkus:quarkus-jdbc-mysql"
参数说明:
projectGroupId
:项目组织标识,通常采用反向域名projectArtifactId
:项目名称extensions
:要包含的Quarkus扩展,多个用逗号分隔,注意要用双引号
2. 使用在线生成器
Quarkus官方提供了Web界面(https://code.quarkus.io),可直观选择需要的扩展并生成项目:
访问code.quarkus.io
选择扩展(如RESTEasy Reactive、Hibernate ORM等)
点击"Generate your application"下载zip包
解压后导入IDE
3. 使用IDE插件
主流Java IDE如IntelliJ IDEA都默认装有Quarkus插件或VS Code都支持通过插件创建Quarkus项目:
安装Quarkus插件
选择"New Project" → "Quarkus"
按照向导填写项目信息
选择初始扩展
项目结构分析
新创建的Quarkus项目遵循标准的Maven结构,但有一些特殊元素:
my-quarkus-app/
├── src/
│ ├── main/
│ │ ├── java/ # 主要Java代码
│ │ ├── resources/
│ │ │ ├── application.properties # 配置文件
│ │ │ └── META-INF/resources/ # 静态资源
│ │ └── docker/ # Docker相关文件
│ └── test/ # 测试代码
├── .dockerignore
├── .gitignore
└── pom.xml # Maven构建文件
关键文件说明:
GreetingResource.java
:自动生成的REST资源类示例application.properties
:统一配置文件,类似Spring的application.propertiesDockerfile.native
:用于构建原生镜像的Dockerfile
核心功能与代码实践
掌握了Quarkus的基本概念和项目创建后,让我们继续深入探讨Quarkus的核心功能,并通过实际代码示例演示如何开发各种云原生组件。这些实践将帮助您全面了解Quarkus的开发模式和最佳实践。
RESTful服务开发
作为微服务的核心构建块,RESTful API在Quarkus中得到了优雅的实现。Quarkus支持两种REST实现:传统的RESTEasy(JAX-RS)和新一代的RESTEasy Reactive。
基础REST端点
以下代码展示了一个简单的REST端点,返回"Hello Quarkus!":
package org.acme;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
@Path("/hello")
public class GreetingResource {
@GET
@Produces(MediaType.TEXT_PLAIN)
public String hello() {
return "Hello Quarkus!";
}
}
关键注解:
@Path
:定义资源路径@GET
:指定HTTP方法@Produces
:声明响应内容类型
启动应用后,访问http://localhost:8080/hello即可看到结果。
RESTEasy Reactive
Quarkus引入了RESTEasy Reactive,它基于Vert.x的异步非阻塞IO,特别适合高并发场景:
@Path("/reactive")
public class ReactiveResource {
@GET
@Produces(MediaType.TEXT_PLAIN)
public Uni<String> reactiveHello() {
return Uni.createFrom().item("Hello Reactive!")
.onItem().delayIt().by(Duration.ofSeconds(1));
}
}
这里使用了Mutiny的Uni
类型,它代表可能尚未完成的异步操作。
异常处理
健壮的API需要良好的错误处理机制:
@GET
@Path("/{name}")
public String personalizedHello(@PathParam String name) {
if(name == null || name.isEmpty()) {
throw new BadRequestException("Name cannot be empty");
}
return "Hello " + name;
}
数据库访问
Quarkus提供了多种数据库访问方式,包括传统的JPA/Hibernate和更轻量级的Panache。
Hibernate ORM with Panache
Panache通过活动记录(Active Record)和仓库(Repository)模式简化了数据访问:
首先添加依赖:
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-hibernate-orm-panache</artifactId>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-jdbc-mysql</artifactId>
</dependency>
<!-- 没有引入这个依赖的话在post请求body的时候一直报415 -->
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-resteasy-reactive-jackson</artifactId>
</dependency>
配置数据源:
# application.properties
# 日志等级,利于排错
quarkus.log.level=DEBUG
quarkus.log.console.level=DEBUG
# 数据源
quarkus.datasource.db-kind=mysql
quarkus.datasource.username=quarkus
quarkus.datasource.password=quarkus
quarkus.datasource.jdbc.url=jdbc:mysql://localhost:3306/quarkus_demo
定义实体:
@Entity(name="person")
public class Person extends PanacheEntityBase {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY) // 使用数据库自增长
public Long id;
public String name;
public String birth;
public String status;
}
实现REST端点:
@Path("/person")
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON)
public class PersonResource {
@GET
public List<Person> list() {
return Person.listAll();
}
@POST
@Transactional
public Response create(Person person) {
person.persist();
return Response.status(201).build();
}
}
Panache提供了大量内置方法如listAll()
、persist()
等,显著减少样板代码。
依赖注入
Quarkus采用CDI(Contexts and Dependency Injection)作为其依赖注入框架:
@ApplicationScoped
public class GreetingService {
public String greet(String name) {
return "Hello " + name;
}
}
@Path("/greet")
public class GreetingResource {
@Inject
GreetingService service;
@GET
@Path("/{name}")
public String greet(@PathParam String name) {
return service.greet(name);
}
}
Quarkus的DI具有以下特点:
支持多种作用域:
@ApplicationScoped
、@RequestScoped
等,似曾相识呀!忘了当初是strutcs还是springmvc用过了...支持
@Inject
和CDI标准编译时验证依赖关系
配置管理
Quarkus提供统一的配置系统,支持多种配置源:
application.properties
:
greeting.message=Hello
greeting.upper-case=false
通过
@ConfigProperty
注入:
@ConfigProperty(name="greeting.message")
String message;
@ConfigProperty(name="greeting.upper-case", defaultValue="true")
boolean upperCase;
支持多环境配置:
# application-dev.properties
quarkus.http.port=9091
# application-prod.properties
quarkus.http.port=8080
通过quarkus.profile
系统属性指定环境:
./mvnw quarkus:dev -Dquarkus.profile=prod
Quarkus还支持从环境变量、Kubernetes ConfigMap等获取配置。
开发模式与测试
Quarkus不仅在生产环境中表现出色,还特别注重开发者的工作效率和体验。其独特的开发模式和全面的测试支持,让开发者能够快速迭代并保证代码质量。
开发模式与热重载
Quarkus的开发模式是提升生产力的关键特性。通过以下命令启动:
./mvnw quarkus:dev
开发模式提供以下强大功能:
热重载:修改Java文件、配置文件或静态资源后,无需手动重启,Quarkus会自动检测并重新加载变更。这是通过字节码增强技术实现的,修改代码后通常1秒内就能看到变化。
开发者控制台:访问http://localhost:8080/q/dev 可进入Dev UI,这里提供了:
查看所有端点
数据库管理工具
配置信息查看器
扩展管理界面
实时日志:控制台输出详细的日志信息,包括启动时间、注册的资源类、配置的数据库连接等。
持续测试:在开发模式下运行测试时,Quarkus会监控代码变化并自动重新运行相关测试。
# 开发模式下运行测试
./mvnw quarkus:test
单元测试
Quarkus鼓励测试驱动开发,提供了全面的测试支持。以下是一个REST端点的测试示例:
@QuarkusTest
public class GreetingResourceTest {
@Test
public void testHelloEndpoint() {
given()
.when().get("/hello")
.then()
.statusCode(200)
.body(is("Hello Quarkus!"));
}
}
关键点:
@QuarkusTest
注解标记测试类使用RestAssured简化HTTP测试
测试会自动在开发模式下运行
集成测试
对于需要数据库或其他外部服务的测试,Quarkus提供了测试资源管理:
@QuarkusTest
@TestHTTPEndpoint(PersonResource.class)
public class PersonResourceTest {
@Test
public void testCreatePerson() {
Person person = new Person();
person.name = "Alice";
given()
.body(person)
.contentType(ContentType.JSON)
.when().post()
.then()
.statusCode(201);
}
}
Quarkus还支持:
@TestProfile
:定义特定测试配置@InjectMock
:注入模拟对象@QuarkusMock
:模拟CDI bean
数据库测试
测试数据库交互时,可以使用H2内存数据库或Testcontainers:
@QuarkusTest
@TestProfile(TestProfile.class)
public class PersonRepositoryTest {
@Inject
PersonRepository repository;
@Test
public void testPersist() {
Person person = new Person();
person.name = "Bob";
repository.persist(person);
assertNotNull(person.id);
}
}
public class TestProfile implements QuarkusTestProfile {
@Override
public Map<String, String> getConfigOverrides() {
return Map.of(
"quarkus.datasource.db-kind", "h2",
"quarkus.datasource.jdbc.url", "jdbc:h2:mem:test"
);
}
}
这种灵活的测试支持确保了应用在各种场景下的行为正确性。
构建与部署
开发完成后,将Quarkus应用高效地构建并部署到生产环境是至关重要的环节。Quarkus提供了多种构建和部署选项,适应不同的运行环境和性能需求。
构建选项
Quarkus支持三种主要的构建模式,每种适合不同的场景:
1. JVM模式
这是最传统的构建方式,生成在JVM上运行的字节码:
./mvnw package
生成的
target/quarkus-app
目录包含:
quarkus-run.jar
:可运行的主JARlib/
:依赖库目录app/
:应用类和资源文件
运行方式:
java -jar target/quarkus-app/quarkus-run.jar
特点:
兼容性好
支持动态类加载和反射
启动速度和内存占用优于传统Java框架但仍不及原生镜像
2. 原生镜像模式
利用GraalVM将应用编译为本地可执行文件:
./mvnw package -Pnative
要求:
已安装GraalVM
配置了必要的环境变量(GRAALVM_HOME)
对于Linux/macOS,需要安装native-image组件
优势:
启动时间:毫秒级(通常<0.1秒)
内存占用:降低80%以上
打包体积:更小的容器镜像
限制:
构建时间较长
某些Java特性(如反射、动态代理)需要特别处理
调试相对困难
3. 选择quarkus的maven插件
容器化部署
Quarkus与Docker和Kubernetes有深度集成,简化了云原生部署。
生成Dockerfile
Quarkus在项目构建时在docker目录下自动生成了多种Dockerfile模板:
JVM模式Dockerfile:
FROM registry.access.redhat.com/ubi8/openjdk-21:1.19
ENV LANGUAGE='en_US:en'
# We make four distinct layers so if there are application changes the library layers can be re-used
COPY --chown=185 target/quarkus-app/lib/ /deployments/lib/
COPY --chown=185 target/quarkus-app/*.jar /deployments/
COPY --chown=185 target/quarkus-app/app/ /deployments/app/
COPY --chown=185 target/quarkus-app/quarkus/ /deployments/quarkus/
EXPOSE 8080
USER 185
ENV JAVA_OPTS_APPEND="-Dquarkus.http.host=0.0.0.0 -Djava.util.logging.manager=org.jboss.logmanager.LogManager"
ENV JAVA_APP_JAR="/deployments/quarkus-run.jar"
ENTRYPOINT [ "/opt/jboss/container/java/run/run-java.sh" ]
原生模式Dockerfile:
FROM quay.io/quarkus/quarkus-micro-image:2.0
WORKDIR /work/
RUN chown 1001 /work \
&& chmod "g+rwX" /work \
&& chown 1001:root /work
COPY --chown=1001:root target/*-runner /work/application
EXPOSE 8080
USER 1001
ENTRYPOINT ["./application", "-Dquarkus.http.host=0.0.0.0"]
生成命令:
./mvnw quarkus:add-extension -Dextensions="container-image-docker"
构建容器镜像
使用Quarkus容器镜像扩展简化构建:
# JVM模式
./mvnw package -Dquarkus.container-image.build=true
# 原生模式
./mvnw package -Pnative -Dquarkus.container-image.build=true
这些命令会自动:
打包应用
构建Docker镜像
标记镜像
Kubernetes集成
Quarkus提供了强大的Kubernetes支持:
添加扩展:
./mvnw quarkus:add-extension -Dextensions="kubernetes"
配置application.properties:
quarkus.kubernetes.deploy=true
quarkus.kubernetes.client.trust-certs=true
quarkus.container-image.registry=quay.io
quarkus.container-image.group=mygroup
构建时将自动生成:
kubernetes.json
kubernetes.yml
并自动部署(如果配置了deploy=true)
部署策略选择
根据应用场景选择最佳部署方式:
无论选择哪种方式,Quarkus都提供了相应的工具和扩展来简化部署流程,真正实现了"构建一次,随处运行"的理念。