The English version of quarkus.io is the official project site. Translated sites are community supported on a best-effort basis.
返回指南目录

创建你的第一个应用程序

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

  • 创建一个应用程序

  • 创建一个JAX-RS端点

  • 注入beans

  • 功能测试

  • 应用程序打包

1. 先决条件

完成这个指南,你需要:

  • 大概15分钟

  • 编辑器

  • 安装JDK 11以上版本并正确配置了 JAVA_HOME

  • Apache Maven 3.8.6

  • 如果你愿意的话,还可以选择使用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。

应用结构,

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

3. 解决方案

我们建议你按照从 构建项目 开始的指示,一步一步地创建应用程序。

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

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

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

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

4. 创建项目

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

针对Linux和MacOS用户

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

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

关于如何安装并使用Quarkus CLI的更多信息,请参考Quarkus CLI指南

Maven
mvn io.quarkus.platform:quarkus-maven-plugin:2.14.2.Final:create \
    -DprojectGroupId=org.acme \
    -DprojectArtifactId=getting-started \
    -Dextensions='resteasy-reactive'
cd getting-started

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

对于Windows用户

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

  • 如果使用Powershell,用双引号包住 -D 参数,例如: "-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-bom</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-resteasy-reactive</artifactId>
</dependency>
build.gradle
implementation("io.quarkus:quarkus-resteasy-reactive")

4.1. JAX-RS的资源

在项目创建过程中, src/main/java/org/acme/GreetingResource.java 文件已被创建,其内容如下:

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 from RESTEasy Reactive";
    }
}

这是一个非常简单的REST端点,对"/hello "上的请求返回 "Hello from RESTEasy Reactive"。

与vanilla JAX-RS的区别

使用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, resteasy-reactive]

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

$ curl -w "\n" http://localhost:8080/hello
Hello from RESTEasy Reactive

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

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

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

6. 使用注入法

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

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

ArC作为 quarkus-resteasy-reactive 的一个依赖项,所以你已经有了。

让我们修改应用程序并添加一个bean。创建 src/main/java/org/acme/GreetingService.java 文件,内容如下。

package org.acme;

import javax.enterprise.context.ApplicationScoped;

@ApplicationScoped
public class GreetingService {

    public String greeting(String name) {
        return "hello " + name;
    }

}

编辑 GreetingResource 类,注入 GreetingService ,并使用它创建一个新的端点:

package org.acme;

import javax.inject.Inject;
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 {

    @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";
    }
}

如果你停止了应用程序(请记住,你不必这样做,变化将由我们的实时重载功能自动部署),用以下方法重新启动应用程序:

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"));
    }

    @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在构建时大量使用 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 ),否则你会有一个端口冲突。

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. 下一步做什么?

本指南涵盖了使用 Quarkus 创建应用程序的内容。 然而,下面还有更多内容。 我们建议您继续学习 构建本地可执行文件指南,您可以在其中了解如何创建本地可执行文件并将其打包到容器中。 如果您对响应式感兴趣,我们推荐 响应式入门指南,您可以在其中了解如何使用 Quarkus 实现响应式应用程序。

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

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

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

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

  • 更多