创建您的第一个应用程序
学习如何创建一个 Hello World Quarkus 应用。本指南涵盖
-
引导应用程序
-
创建 Jakarta REST 端点
-
注入 Bean
-
功能测试
-
应用程序的打包
1. 前提条件
要完成本指南,您需要
-
大约 15 分钟
-
一个 IDE
-
已安装 JDK 17+ 并正确配置了
JAVA_HOME
-
Apache Maven 3.9.9
-
如果您想使用它,可以选择 Quarkus CLI
验证 Maven 是否使用您期望的 Java
如果您安装了多个 JDK,则不能确定 Maven 会选择预期的 Java,您最终可能会得到意想不到的结果。您可以通过运行 |
4. 引导项目
创建新的 Quarkus 项目的最简单方法是打开一个终端并运行以下命令
对于 Windows 用户
-
如果使用 cmd,(不要使用反斜杠
\
并将所有内容放在同一行上) -
如果使用 Powershell,请用双引号将
-D
参数括起来,例如"-DprojectArtifactId=getting-started"
它在 ./getting-started
中生成以下内容
-
Maven 结构
-
在
/hello
上公开的org.acme.GreetingResource
资源 -
相关的单元测试
-
启动应用程序后,可以在
https://:8080
上访问的登陆页面 -
在
src/main/docker
中用于native
和jvm
模式的示例Dockerfile
文件 -
应用程序配置文件
生成后,查看 pom.xml
。您将找到 Quarkus BOM 的导入,允许您省略不同 Quarkus 依赖项的版本。此外,您还可以看到负责应用程序打包并提供开发模式的 quarkus-maven-plugin
。
<dependencyManagement>
<dependencies>
<dependency>
<groupId>${quarkus.platform.group-id}</groupId>
<artifactId>${quarkus.platform.artifact-id}</artifactId>
<version>${quarkus.platform.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<plugins>
<plugin>
<groupId>${quarkus.platform.group-id}</groupId>
<artifactId>quarkus-maven-plugin</artifactId>
<version>${quarkus.platform.version}</version>
<extensions>true</extensions>
<executions>
<execution>
<goals>
<goal>build</goal>
<goal>generate-code</goal>
<goal>generate-code-tests</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
在 Gradle 项目中,您会找到类似的设置
-
Quarkus Gradle 插件
-
Quarkus BOM 的
enforcedPlatform
指令
如果我们关注依赖项部分,您可以看到允许开发 REST 应用程序的扩展
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-rest</artifactId>
</dependency>
implementation("io.quarkus:quarkus-rest")
4.1. Jakarta REST 资源
在项目创建期间,已创建了 src/main/java/org/acme/GreetingResource.java
文件,其内容如下
package org.acme;
import jakarta.ws.rs.GET;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.Produces;
import jakarta.ws.rs.core.MediaType;
@Path("/hello")
public class GreetingResource {
@GET
@Produces(MediaType.TEXT_PLAIN)
public String hello() {
return "Hello from Quarkus REST";
}
}
这是一个非常简单的 REST 端点,它向 "/hello" 上的请求返回 "Hello from Quarkus REST"。
与 Vanilla Jakarta REST 的区别
使用 Quarkus,无需创建 |
5. 运行应用程序
现在我们准备好运行我们的应用程序
quarkus dev
./mvnw quarkus:dev
./gradlew --console=plain quarkusDev
[INFO] --------------------< org.acme:getting-started >---------------------
[INFO] Building getting-started 1.0.0-SNAPSHOT
[INFO] --------------------------------[ jar ]---------------------------------
[INFO]
[INFO] --- maven-resources-plugin:2.6:resources (default-resources) @ getting-started ---
[INFO] Using 'UTF-8' encoding to copy filtered resources.
[INFO] skip non existing resourceDirectory <path>/getting-started/src/main/resources
[INFO]
[INFO] --- maven-compiler-plugin:3.1:compile (default-compile) @ getting-started ---
[INFO] Changes detected - recompiling the module!
[INFO] Compiling 2 source files to <path>/getting-started/target/classes
[INFO]
[INFO] --- quarkus-maven-plugin:<version>:dev (default-cli) @ getting-started ---
Listening for transport dt_socket at address: 5005
2019-02-28 17:05:22,347 INFO [io.qua.dep.QuarkusAugmentor] (main) Beginning quarkus augmentation
2019-02-28 17:05:22,635 INFO [io.qua.dep.QuarkusAugmentor] (main) Quarkus augmentation completed in 288ms
2019-02-28 17:05:22,770 INFO [io.quarkus] (main) Quarkus started in 0.668s. Listening on: https://:8080
2019-02-28 17:05:22,771 INFO [io.quarkus] (main) Installed features: [cdi, rest]
启动后,您可以请求提供的端点
$ curl -w "\n" https://:8080/hello
Hello from Quarkus REST
按 CTRL+C
停止应用程序,或使其保持运行并享受极速的热重载。
使用
curl -w "\n" 自动添加换行符我们在此示例中使用 |
6. 使用注入
Quarkus 中的依赖注入基于 ArC,它是一种基于 CDI 的依赖注入解决方案,专为 Quarkus 的架构量身定制。如果您是 CDI 的新手,我们建议您阅读 CDI 简介 指南。
Quarkus 仅实现了 CDI 功能的一个子集,并带有非标准功能和特定 APIS,您可以在 上下文和依赖注入指南中了解更多信息。
ArC 作为 quarkus-rest
的依赖项出现,因此您已经方便地拥有了它。
让我们修改应用程序并添加一个伴随 Bean。创建 src/main/java/org/acme/GreetingService.java
文件,其内容如下
package org.acme;
import jakarta.enterprise.context.ApplicationScoped;
@ApplicationScoped
public class GreetingService {
public String greeting(String name) {
return "hello " + name;
}
}
编辑 GreetingResource
类以注入 GreetingService
并创建一个使用它的新端点
package org.acme;
import jakarta.inject.Inject;
import jakarta.ws.rs.GET;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.Produces;
import jakarta.ws.rs.core.MediaType;
@Path("/hello")
public class GreetingResource {
@Inject
GreetingService service;
@GET
@Produces(MediaType.TEXT_PLAIN)
@Path("/greeting/{name}")
public String greeting(String name) {
return service.greeting(name);
}
@GET
@Produces(MediaType.TEXT_PLAIN)
public String hello() {
return "Hello from Quarkus REST";
}
}
如果您停止了应用程序(请记住您不必这样做,我们的实时重新加载功能会自动部署更改),请使用以下命令重新启动应用程序
quarkus dev
./mvnw quarkus:dev
./gradlew --console=plain quarkusDev
然后检查端点是否按预期返回 hello quarkus
$ curl -w "\n" https://:8080/hello/greeting/quarkus
hello quarkus
7. 开发模式
quarkus:dev
在开发模式下运行 Quarkus。这启用了带后台编译的实时重新加载,这意味着当您修改 Java 文件和/或资源文件并刷新浏览器时,这些更改将自动生效。这也适用于配置文件等资源文件。刷新浏览器会触发工作空间的扫描,如果检测到任何更改,Java 文件将被重新编译并且应用程序将被重新部署;然后您的请求将由重新部署的应用程序提供服务。如果编译或部署有任何问题,错误页面会通知您。
这也会侦听端口 5005
上的调试器。如果您想在运行之前等待调试器附加,您可以在命令行上传递 -Dsuspend
。如果您根本不需要调试器,您可以使用 -Ddebug=false
。
8. 测试
好吧,到目前为止还不错,但如果进行一些测试会更好吗?
在生成的构建文件中,您可以看到 2 个测试依赖项
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-junit5</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.rest-assured</groupId>
<artifactId>rest-assured</artifactId>
<scope>test</scope>
</dependency>
testImplementation("io.quarkus:quarkus-junit5")
testImplementation("io.rest-assured:rest-assured")
Quarkus 支持 JUnit 5 测试。
因此,在 Maven 的情况下,必须设置 Surefire Maven 插件 的版本,因为默认版本不支持 JUnit 5
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<version>${surefire-plugin.version}</version>
<configuration>
<systemPropertyVariables>
<java.util.logging.manager>org.jboss.logmanager.LogManager</java.util.logging.manager>
<maven.home>${maven.home}</maven.home>
</systemPropertyVariables>
</configuration>
</plugin>
我们还设置了 java.util.logging
系统属性以确保测试将使用正确的日志管理器,并设置了 maven.home
以确保应用来自 ${maven.home}/conf/settings.xml
的自定义配置(如果有)。
生成的项目包含一个简单的测试。编辑 src/test/java/org/acme/GreetingResourceTest.java
以匹配以下内容
package org.acme;
import io.quarkus.test.junit.QuarkusTest;
import org.junit.jupiter.api.Test;
import java.util.UUID;
import static io.restassured.RestAssured.given;
import static org.hamcrest.CoreMatchers.is;
@QuarkusTest
public class GreetingResourceTest {
@Test (1)
public void testHelloEndpoint() {
given()
.when().get("/hello")
.then()
.statusCode(200) (2)
.body(is("Hello from Quarkus REST"));
}
@Test
public void testGreetingEndpoint() {
String uuid = UUID.randomUUID().toString();
given()
.pathParam("name", uuid)
.when().get("/hello/greeting/{name}")
.then()
.statusCode(200)
.body(is("hello " + uuid));
}
}
1 | 通过使用 QuarkusTest 运行器,您可以指示 JUnit 在测试之前启动应用程序。 |
2 | 检查 HTTP 响应状态代码和内容 |
这些测试使用 RestAssured,但您可以随意使用您喜欢的库。
您可以使用 Maven 运行这些测试
./mvnw test
您也可以直接从您的 IDE 运行测试(请确保您首先停止了应用程序)。
默认情况下,测试将在端口 8081
上运行,以免与正在运行的应用程序发生冲突。我们会自动配置 RestAssured 以使用此端口。如果您想使用不同的客户端,您应该使用 @TestHTTPResource
注释将经过测试的应用程序的 URL 直接注入到测试类上的字段中。此字段的类型可以是 String
、URL
或 URI
。此注释也可以为测试路径提供一个值。例如,如果我想测试映射到 /myservlet
的 Servlet,我只需将以下内容添加到我的测试中
@TestHTTPResource("/myservlet")
URL testUrl;
测试端口可以通过 quarkus.http.test-port
配置属性控制。Quarkus 还创建一个名为 test.url
的系统属性,该属性设置为基本测试 URL,以用于无法使用注入的情况。
9. 使用多模块项目或外部模块
Quarkus 在构建时大量利用 Jandex 来发现各种类或注释。这方面一个立即可识别的应用是 CDI Bean 发现。因此,如果未正确设置此构建时发现,则大多数 Quarkus 扩展将无法正常工作。
由于我们的 Maven 和 Gradle 插件,此索引默认在配置了 Quarkus 的项目上创建。
如果您计划使用外部模块(例如,用于所有域对象的外部库),您将需要通过添加 Jandex 插件(如果您可以修改它们)或通过 application.properties
中的 quarkus.index-dependency
属性(在您无法修改模块的情况下很有用)使这些模块对索引过程已知。
请务必阅读 CDI 指南的 Bean 发现 部分以获取更多信息。
10. 打包和运行应用程序
应用程序使用以下命令打包
quarkus build
./mvnw install
./gradlew build
它在 /target
中生成几个输出
-
getting-started-1.0.0-SNAPSHOT.jar
- 仅包含项目的类和资源,它是 Maven 构建生成的常规工件 - 它不是可运行的 jar; -
quarkus-app
目录,其中包含quarkus-run.jar
jar 文件 - 它是可执行的 jar。请注意,它不是 über-jar,因为依赖项被复制到quarkus-app/lib/
的子目录中。
您可以使用以下命令运行应用程序:java -jar target/quarkus-app/quarkus-run.jar
如果您想在某处部署您的应用程序(通常在容器中),您需要部署整个 quarkus-app 目录。 |
在运行应用程序之前,不要忘记停止热重载模式(按 CTRL+C ),否则您将遇到端口冲突。 |
11. 配置横幅
默认情况下,当 Quarkus 应用程序启动时(在常规模式或开发模式下),它将显示一个 ASCII 艺术横幅。可以通过在 application.properties
中设置 quarkus.banner.enabled=false
,通过设置 -Dquarkus.banner.enabled=false
Java 系统属性,或通过将 QUARKUS_BANNER_ENABLED
环境变量设置为 false
来禁用横幅。此外,用户可以通过将横幅文件放置在 src/main/resources
中并在 application.properties
中配置 quarkus.banner.path=name-of-file
来提供自定义横幅。
12. 非应用程序端点
这些非应用程序端点通常可以在 /q
前缀下访问,如下所示
-
/q/health
-
/q/metrics
-
/q/openapi
-
/q/info
但是用户也可以选择使用专用的 管理界面 在不同的 TCP 端口下公开可能存在安全风险的端点。
12.1. 信息端点
如果应用程序包含 quarkus-info
扩展,那么 Quarkus 默认会公开 /q/info
端点,该端点提供有关构建、Java 版本、版本控制和操作系统的信息。公开信息的详细程度是可配置的。
所有实现 InfoContributor
的 CDI Bean 都将被拾取,它们的数据将被附加到端点。
13. 接下来是什么?
本指南介绍了使用 Quarkus 创建应用程序。但是,还有更多内容。我们建议通过创建 您的第二个 Quarkus 应用程序(使用 Dev Services 和持久性)来继续您的旅程。您可以通过 构建本机可执行文件指南了解如何创建本机可执行文件并将其打包到容器中。如果您对响应式感兴趣,我们建议阅读 响应式入门指南,您可以在其中了解如何使用 Quarkus 实现响应式应用程序。
此外,工具指南文档解释了如何
-
在单个命令行中搭建项目
-
启用开发模式(热重载)
-
在您喜欢的 IDE 中导入项目
-
等等