编辑此页面

创建您的第一个应用程序

学习如何创建一个 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,您最终可能会得到意想不到的结果。您可以通过运行 mvn --version 来验证 Maven 使用哪个 JDK。

2. 架构

在本指南中,我们将创建一个简单的应用程序,提供一个 hello 端点。为了演示依赖注入,此端点使用一个 greeting Bean。

Architecture

本指南还涵盖了端点的测试。

3. 解决方案

我们建议您按照引导项目及后续步骤中的说明逐步创建应用程序。

但是,您可以直接转到完整的示例。

下载 存档 或克隆 Git 存储库

git clone https://github.com/quarkusio/quarkus-quickstarts.git

解决方案位于 getting-started 目录 中。

4. 引导项目

创建新的 Quarkus 项目的最简单方法是打开一个终端并运行以下命令

CLI
quarkus create app org.acme:getting-started \
    --extension='rest'
cd getting-started

要创建 Gradle 项目,请添加 --gradle--gradle-kotlin-dsl 选项。

有关如何安装和使用 Quarkus CLI 的更多信息,请参阅 Quarkus CLI 指南。

Maven
mvn io.quarkus.platform:quarkus-maven-plugin:3.24.4:create \
    -DprojectGroupId=org.acme \
    -DprojectArtifactId=getting-started \
    -Dextensions='rest'
cd getting-started

要创建 Gradle 项目,请添加 -DbuildTool=gradle-DbuildTool=gradle-kotlin-dsl 选项。

对于 Windows 用户

  • 如果使用 cmd,(不要使用反斜杠 \ 并将所有内容放在同一行上)

  • 如果使用 Powershell,请用双引号将 -D 参数括起来,例如 "-DprojectArtifactId=getting-started"

它在 ./getting-started 中生成以下内容

  • Maven 结构

  • /hello 上公开的 org.acme.GreetingResource 资源

  • 相关的单元测试

  • 启动应用程序后,可以在 https://:8080 上访问的登陆页面

  • src/main/docker 中用于 nativejvm 模式的示例 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 应用程序的扩展

pom.xml
<dependency>
    <groupId>io.quarkus</groupId>
    <artifactId>quarkus-rest</artifactId>
</dependency>
build.gradle
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,无需创建 Application 类。它被支持,但不是必需的。此外,仅创建一个资源实例,而不是每个请求一个。您可以使用不同的 *Scoped 注释(ApplicationScopedRequestScoped 等)配置此行为。

5. 运行应用程序

现在我们准备好运行我们的应用程序

CLI
quarkus dev
Maven
./mvnw quarkus:dev
Gradle
./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" 自动添加换行符

我们在此示例中使用 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";
    }
}

如果您停止了应用程序(请记住您不必这样做,我们的实时重新加载功能会自动部署更改),请使用以下命令重新启动应用程序

CLI
quarkus dev
Maven
./mvnw quarkus:dev
Gradle
./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 个测试依赖项

pom.xml
<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>
build.gradle
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 直接注入到测试类上的字段中。此字段的类型可以是 StringURLURI。此注释也可以为测试路径提供一个值。例如,如果我想测试映射到 /myservlet 的 Servlet,我只需将以下内容添加到我的测试中

@TestHTTPResource("/myservlet")
URL testUrl;

测试端口可以通过 quarkus.http.test-port 配置属性控制。Quarkus 还创建一个名为 test.url 的系统属性,该属性设置为基本测试 URL,以用于无法使用注入的情况。

9. 使用多模块项目或外部模块

Quarkus 在构建时大量利用 Jandex 来发现各种类或注释。这方面一个立即可识别的应用是 CDI Bean 发现。因此,如果未正确设置此构建时发现,则大多数 Quarkus 扩展将无法正常工作。

由于我们的 Maven 和 Gradle 插件,此索引默认在配置了 Quarkus 的项目上创建。

但是,在使用多模块项目时,请务必阅读 MavenGradle 指南的 使用多模块项目 部分。

如果您计划使用外部模块(例如,用于所有域对象的外部库),您将需要通过添加 Jandex 插件(如果您可以修改它们)或通过 application.properties 中的 quarkus.index-dependency 属性(在您无法修改模块的情况下很有用)使这些模块对索引过程已知。

请务必阅读 CDI 指南的 Bean 发现 部分以获取更多信息。

10. 打包和运行应用程序

应用程序使用以下命令打包

CLI
quarkus build
Maven
./mvnw install
Gradle
./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),否则您将遇到端口冲突。

默认情况下,当 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. 非应用程序端点

各种 Quarkus 扩展会贡献非应用程序端点,这些端点提供有关应用程序的不同类型的信息。此类扩展的示例包括 健康检查指标OpenAPI 和信息扩展。

这些非应用程序端点通常可以在 /q 前缀下访问,如下所示

  • /q/health

  • /q/metrics

  • /q/openapi

  • /q/info

但是用户也可以选择使用专用的 管理界面 在不同的 TCP 端口下公开可能存在安全风险的端点。

12.1. 信息端点

如果应用程序包含 quarkus-info 扩展,那么 Quarkus 默认会公开 /q/info 端点,该端点提供有关构建、Java 版本、版本控制和操作系统的信息。公开信息的详细程度是可配置的。

所有实现 InfoContributor 的 CDI Bean 都将被拾取,它们的数据将被附加到端点。

12.1.1. 配置参考

构建时固定的配置属性 - 所有其他配置属性都可以在运行时覆盖

配置属性

类型

默认

是否启用信息端点

环境变量:QUARKUS_INFO_ENABLED

显示更多

布尔值

true

信息端点所在的路径

环境变量:QUARKUS_INFO_PATH

显示更多

字符串

info

是否在信息端点中包含 Git 信息

环境变量:QUARKUS_INFO_GIT_ENABLED

显示更多

布尔值

true

控制 Git 部分中存在多少信息

环境变量:QUARKUS_INFO_GIT_MODE

显示更多

standard, full

standard

是否在信息端点中包含构建信息

环境变量:QUARKUS_INFO_BUILD_ENABLED

显示更多

布尔值

true

要添加到构建部分的其他属性

环境变量:QUARKUS_INFO_BUILD__PROPERTY_KEY_

显示更多

Map<String,String>

是否在信息端点中包含操作系统信息

环境变量:QUARKUS_INFO_OS_ENABLED

显示更多

布尔值

true

是否在信息端点中包含 Java 信息

环境变量:QUARKUS_INFO_JAVA_ENABLED

显示更多

布尔值

true

13. 接下来是什么?

本指南介绍了使用 Quarkus 创建应用程序。但是,还有更多内容。我们建议通过创建 您的第二个 Quarkus 应用程序(使用 Dev Services 和持久性)来继续您的旅程。您可以通过 构建本机可执行文件指南了解如何创建本机可执行文件并将其打包到容器中。如果您对响应式感兴趣,我们建议阅读 响应式入门指南,您可以在其中了解如何使用 Quarkus 实现响应式应用程序。

此外,工具指南文档解释了如何

  • 在单个命令行中搭建项目

  • 启用开发模式(热重载)

  • 在您喜欢的 IDE 中导入项目

  • 等等

相关内容