The English version of quarkus.io is the official project site. Translated sites are community supported on a best-effort basis.

创建你的第一个应用程序

学习如何创建一个Hello World Quarkus应用程序。本指南包括:

  • 创建一个应用程序

  • Creating a Jakarta REST endpoint

  • 注入beans

  • 功能测试

  • 应用程序打包

1. 先决条件

完成这个指南,你需要:

  • 大概15分钟

  • 编辑器

  • JDK 17+ installed with JAVA_HOME configured appropriately

  • Apache Maven 3.9.9

  • 如果你愿意的话,还可以选择使用Quarkus CLI

验证Maven是否使用了你期望的Java版本

If you have multiple JDK’s installed, it is not certain Maven will pick up the expected java and you could end up with unexpected results. You can verify which JDK Maven uses by running mvn --version.

2. 应用结构

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

Architecture

本指南还包括对终端的测试。

3. 解决方案

We recommend that you follow the instructions from Bootstrapping the project and onwards to create the application step by step.

然而,你可以直接进入完成的例子。

下载一个 存档 或克隆git仓库:

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

The solution is located in the getting-started directory.

4. 创建项目

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

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

创建Grade项目,请添加 --gradle 或者 --gradle-kotlin-dsl 参数。

For more information about how to install and use the Quarkus CLI, see the Quarkus CLI guide.

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

创建Grade项目,请添加 -DbuildTool=gradle 或者 -DbuildTool=gradle-kotlin-dsl 参数。

For Windows users:

  • If using cmd, (don’t use backward slash \ and put everything on the same line)

  • If using Powershell, wrap -D parameters in double quotes e.g. "-DprojectArtifactId=getting-started"

它在 ./getting-started 中产生了以下内容:

  • Maven的结构

  • 通过 /hello 暴露出来的 org.acme.GreetingResource 资源

  • 相关的单元测试

  • 启动应用程序后,可以通过 http://localhost:8080 访问的登陆页面

  • 示例 Dockerfile 文件,用于 nativejvm 两种模式,在 src/main/docker

  • 应用程序的配置文件

一旦生成,请看 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插件

  • enforcedPlatform ,用于指示Quarkus BOM

如果我们把重点放在依赖关系部分,你可以看到允许开发REST应用程序的扩展:

pom.xml
<dependency>
    <groupId>io.quarkus</groupId>
    <artifactId>quarkus-rest</artifactId>
</dependency>
build.gradle
implementation("io.quarkus:quarkus-rest")

4.1. The Jakarta REST resources

在项目创建过程中, 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";
    }
}

It’s a very simple REST endpoint, returning "Hello from Quarkus REST" to requests on "/hello".

Differences with vanilla Jakarta REST

使用Quarkus,不需要创建一个 Application 类。它支持这么做,但不是必须的。此外,只有一个资源的实例被创建,而不是每个请求一个。你可以使用不同的 *Scoped 注解( ApplicationScoped , RequestScoped , 等等)来配置。

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: http://localhost:8080
2019-02-28 17:05:22,771 INFO  [io.quarkus] (main) Installed features: [cdi, rest]

一旦启动,你可以发送请求到提供服务的端点。

$ curl -w "\n" http://localhost:8080/hello
Hello from Quarkus REST

点击 CTRL+C ,停止应用程序,或保持运行,享受极快的热重载。

自动添加换行符 curl -w "\n"

我们在这个例子中使用 curl -w "\n" ,以避免你的终端打印出'%'或把结果和下一个命令提示符放在同一行。

6. 使用注入法

Quarkus中的依赖注入是基于ArC的,ArC是一个基于CDI的依赖注入解决方案,。如果你是CDI的新手,那么我们推荐你阅读 CDI简介 指南。

Quarkus只实现了CDI功能的一个子集,并且带有非标准的功能和特定的APIS,你可以在 Contexts和依赖注入指南 中了解更多。

ArC comes as a dependency of quarkus-rest so you already have it handy.

让我们修改应用程序并添加一个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" http://localhost: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 Plugin 的版本,因为默认版本不支持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 runner,你指示JUnit在测试前启动应用程序。
2 检查HTTP回应状态代码和内容

These tests use RestAssured, but feel free to use your favorite library.

你可以用Maven来运行这些:

./mvnw test

你也可以直接从你的IDE中运行测试(要确保你先停止了应用程序)。

默认情况下,测试将在端口 8081 上运行,以便不与正在运行的应用程序冲突。我们自动将RestAssured配置为使用该端口。如果你想使用不同的客户端,你应该使用 @TestHTTPResource 注释,直接将测试应用程序的URL注入到测试类的一个字段中。这个字段的类型可以是 String , URLURI 。这个注解也可以给测试路径一个值。例如,如果我想测试一个映射到 /myservlet 的Servlet,只需在测试中添加以下内容:

@TestHTTPResource("/myservlet")
URL testUrl;

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

9. 与多模块项目或外部模块一起工作

Quarkus heavily utilizes Jandex at build time, to discover various classes or annotations. One immediately recognizable application of this, is CDI bean discovery. As a result, most of the Quarkus extensions will not work properly if this build time discovery isn’t properly setup.

通过使用Maven和Gradle插件,这个索引在Quarkus的项目上的默认配置是自动创建。

However, when working with a multi-module project, be sure to read the Working with multi-module projects section of the Maven or Gradle guides.

如果你计划使用外部模块(例如,一个用于你所有领域对象的外部库),你将需要通过添加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 ),否则你会有一个端口冲突。

By default, when a Quarkus application starts (in regular or dev mode), it will display an ASCII art banner. The banner can be disabled by setting quarkus.banner.enabled=false in application.properties, by setting the -Dquarkus.banner.enabled=false Java System Property, or by setting the QUARKUS_BANNER_ENABLED environment variable to false. Furthermore, users can supply a custom banner by placing the banner file in src/main/resources and configuring quarkus.banner.path=name-of-file in application.properties.

12. Non Application endpoints

Various Quarkus extensions contribute non-application endpoints that provide different kinds of information about the application. Examples of such extensions are the health, metrics, OpenAPI and info extensions.

These non application endpoints are normally accessible under the /q prefix like so:

  • /q/health

  • /q/metrics

  • /q/openapi

  • /q/info

but users can also choose to expose one that might present a security risk under a different TCP port using a dedicated management interface.

12.1. Info endpoint

If the application contains the quarkus-info extension, then Quarkus will by default expose the /q/info endpoint which provides information about the build, java version, version control, and operating system. The level of detail of the exposed information is configurable.

All CDI beans implementing the InfoContributor will be picked up and their data will be appended to the endpoint.

12.1.1. 配置参考

Configuration property fixed at build time - All other configuration properties are overridable at runtime

Configuration property

类型

默认

Whether the info endpoint will be enabled

Environment variable: QUARKUS_INFO_ENABLED

Show more

boolean

true

The path under which the info endpoint will be located

Environment variable: QUARKUS_INFO_PATH

Show more

string

info

Whether git info will be included in the info endpoint

Environment variable: QUARKUS_INFO_GIT_ENABLED

Show more

boolean

true

Controls how much information is present in the git section

Environment variable: QUARKUS_INFO_GIT_MODE

Show more

standard, full

standard

Whether build info will be included in the info endpoint

Environment variable: QUARKUS_INFO_BUILD_ENABLED

Show more

boolean

true

Additional properties to be added to the build section

Environment variable: QUARKUS_INFO_BUILD__PROPERTY_KEY_

Show more

Map<String,String>

Whether os info will be included in the info endpoint

Environment variable: QUARKUS_INFO_OS_ENABLED

Show more

boolean

true

Whether java info will be included in the info endpoint

Environment variable: QUARKUS_INFO_JAVA_ENABLED

Show more

boolean

true

13. 下一步做什么?

This guide covered the creation of an application using Quarkus. However, there is much more. We recommend continuing the journey by creating your second Quarkus application, with Dev Services and persistence. You can learn about creating a native executable and packaging it in a container with the building a native executable guide. If you are interested in reactive, we recommend the getting started with reactive guide, where you can see how to implement reactive applications with Quarkus.

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

  • 在单个命令行中为项目搭建脚手架

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

  • 在你喜欢的编辑器里面导入项目

  • 更多

Related content