Quarkus - 创建你第一个应用

了解如何创建Quarkus Hello World应用程序。 本指南涵盖:

  • 启动应用程序

  • 创建JAX-RS 接口

  • 注入beans

  • 功能测试

  • 应用打包

1. 准备

要完成本指南,您需要:

  • 15 分钟以内

  • 开发工具 IDE

  • 安装 JDK 8或11+,正确配置 JAVA_HOME

  • Apache Maven 3.6.2+

验证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项目的最简单方法是打开命令行并运行以下命令:

Linux和MacOS用户:

mvn io.quarkus:quarkus-maven-plugin:1.3.1.Final:create \
    -DprojectGroupId=org.acme \
    -DprojectArtifactId=getting-started \
    -DclassName="org.acme.getting.started.GreetingResource" \
    -Dpath="/hello"
cd getting-started

Windows用户

  • 如果使用cmd,(不要使用反斜杠 \ )

mvn io.quarkus:quarkus-maven-plugin:1.3.1.Final:create -DprojectGroupId=org.acme -DprojectArtifactId=getting-started -DclassName="org.acme.getting.started.GreetingResource" -Dpath="/hello"
  • 如果使用Powershell,请用双引号将 -D 参数括起来

mvn io.quarkus:quarkus-maven-plugin:1.3.1.Final:create "-DprojectGroupId=org.acme" "-DprojectArtifactId=getting-started" "-DclassName=org.acme.getting.started.GreetingResource" "-Dpath=/hello"

上边命令会在 ./getting-started 中生成以下内容:

  • Maven结构

  • org.acme.getting.started.GreetingResource 接口 /hello

  • 相关单元测试

  • 启动应用程序后可访问 http://localhost:8080 入口页

  • src/main/docker 有 Dockerfile 样例文件,包含 nativejvm 模式 。

  • 应用程序配置文件

生成后,查看 pom.xml 。 您会看到导入了 Quarkus BOM ,让您不用关心 Quarkus 依赖项版本。 此外,您还可以看到负责打包应用程序并提供开发模式的 quarkus-maven-plugin

<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>io.quarkus</groupId>
            <artifactId>quarkus-bom</artifactId>
            <version>${quarkus.version}</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>

<build>
    <plugins>
        <plugin>
            <groupId>io.quarkus</groupId>
            <artifactId>quarkus-maven-plugin</artifactId>
            <version>${quarkus.version}</version>
            <executions>
                <execution>
                    <goals>
                        <goal>build</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
    </plugins>
</build>

如果我们关注依赖关系部分,您可以看到支持 REST 程序开发的扩展:

    <dependency>
        <groupId>io.quarkus</groupId>
        <artifactId>quarkus-resteasy</artifactId>
    </dependency>

4.1. JAX-RS 资源

项目创建生成时,已经创建了 src/main/java/org/acme/getting/started/GreetingResource.java 文件,其中包含以下内容:

package org.acme.getting.started;

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

这是一个非常简单的REST 接口,请求 "/hello" 时返回 "hello" 。

与普通 JAX-RS 的差别

使用 Quarkus,不需要创建 Application 类。能用,但不是必需的。此外,只创建资源类的一个实例,而不是每个请求创建一个实例。(QFY: GreetingResource 是单例)您可以使用不同的 *Scoped 注解 (ApplicationScoped, RequestScoped ,等)对它进行配置。

5. 运行

现在我们可以运行应用程序了。 使用:`./mvnw compile quarkus:dev`:

$ ./mvnw compile quarkus:dev
[INFO] --------------------< org.acme:getting-started >---------------------
[INFO] Building getting-started 1.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 /Users/starksm/Dev/JBoss/Quarkus/starksm64-quarkus-quickstarts/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 /Users/starksm/Dev/JBoss/Quarkus/starksm64-quarkus-quickstarts/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]

启动后,可以请求提供的接口:

$ curl -w "\n" http://localhost:8080/hello
hello

CTRL+C 停止应用程序,或者让它继续运行并享受超快的热加载 (QFY: 修改代码保存后自动重新编译并热加载到运行中的程序去,重新调用接口就能看到更新后的效果)。

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

在本例中,我们使用 curl -w "\n" 来避免终端输出 '%' ,或者将结果和下一个命令提示符放在同一行。

6. 使用注入

Quarkus 中的依赖注入是基于ArC的,ArC是一个基于 CDI 的依赖注入解决方案,专为 Quarkus 设计。 您可以在 上下文依赖注入指南 中了解更多信息。

ArC 是 quarkus-resteasy 的一个依赖项,所以可以直接使用 。

让我们修改应用程序并添加一个辅助 bean。 创建 src/main/java/org/acme/getting/started/GreetingService.java 文件包含以下内容:

package org.acme.getting.started;

import javax.enterprise.context.ApplicationScoped;

@ApplicationScoped
public class GreetingService {

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

}

编辑 GreetingResource 类注入 GreetingService 并在一个新接口中使用它:

package org.acme.getting.started;

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;

import org.jboss.resteasy.annotations.jaxrs.PathParam;

@Path("/hello")
public class GreetingResource {

    @Inject
    GreetingService service;

    @GET
    @Produces(MediaType.TEXT_PLAIN)
    @Path("/greeting/{name}")
    public String greeting(@PathParam String name) {
        return service.greeting(name);
    }

    @GET
    @Produces(MediaType.TEXT_PLAIN)
    public String hello() {
        return "hello";
    }
}

如果已经停止应用程序,请使用 ./mvnw compile quarkus:dev . 重新启动应用程序,然后检查接口是否返回期望的 hello quarkus :

$ curl -w "\n" http://localhost:8080/hello/greeting/quarkus
hello quarkus

7. 开发模式

quarkus:dev 在开发模式下运行 Quarkus 。开发模式会启用后台编译的热部署,这意味着当您修改Java文件或资源文件并刷新浏览器时,这些更改将自动生效。这也适用于配置文件之类的资源文件。

刷新浏览器将触发对工作区的扫描,或者检测到任何更改,将重新编译Java文件并重新部署应用程序;然后用重新部署的应用程序为请求提供服务。

如果编译或部署有任何问题,会显示错误页。

还会监听调试端口 5005 。如果希望在运行之前附加上调试器,可以在命令行上传递参数 -Dsuspend 。如果根本不需要调试器,可以使用 -Ddebug=false

8. 测试

好吧,到目前为止还不错,以防万一,再做一些测试不是更好吗。

在生成的 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>

Quarkus 支持 Junit 5 测试。 要改成 JUnit5,必须设置 Surefire Maven Plugin 的版本,因为默认版本不是 Junit 5:

<plugin>
    <artifactId>maven-surefire-plugin</artifactId>
    <version>${surefire-plugin.version}</version>
    <configuration>
       <systemProperties>
          <java.util.logging.manager>org.jboss.logmanager.LogManager</java.util.logging.manager>
       </systemProperties>
    </configuration>
</plugin>

我们还设置了 java.util.logging 系统属性,以确保测试将使用正确的日志管理器。

生成的项目包含一个简单的测试。 编辑 src/test/java/org/acme/getting/started/GreetingResourceTest.java 改为以下内容:

package org.acme.getting.started;

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响应状态和内容

这些测试使用 RestAssured ,但可以随意使用您喜欢的类库。

您可以使用 Maven 运行测试:

./mvnw test

您也可以直接从IDE运行测试(确保先停止应用程序)。

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

@TestHTTPResource("/myservlet")
URL testUrl;

可以通过 quarkus.http.test-port 配置属性控制测试端口。Quarkus还创建名为 test.url 的系统属性,为无法使用注入的情况下的指定测试网址。

9. 打包并运行应用程序

应用程序使用 ./mvnw package 打包。

它在 /target 中生成2个jar文件:

  • getting-started-1.0-SNAPSHOT.jar - 仅包含项目的类和资源,它是Maven构建生成的常规工件;

  • getting-started-1.0-SNAPSHOT-runner.jar - 可执行的 jar 。 注意,它不是一个 über-jar (QFY: über-jar 一种将所有依赖及代码合并成一个 jar 的打包方式),因为依赖项被复制到 target/lib 目录中。

可以使用以下命令运行应用程序: java -jar target/getting-started-1.0-SNAPSHOT-runner.jar

runner jarMANIFEST.MFClass-Path 项明确指定了 lib 目录中的 jars。 因此,如果要将应用程序部署到某个地方,需要复制 runner jar 和 lib 目录。
在运行应用程序之前,不要忘记停止热重新加载模式(按 CTRL+C ),否则会出现端口冲突。

默认情况下,当Quarkus应用程序启动时(在常规或开发模式下),它将显示一幅 ASCII 字符拼成的的 banner 横幅。可以通过在 application.properties 中设置 quarkus.banner.enabled=false 、 Java系统属性 -Dquarkus.banner.enabled=false 或将环境变量 QUARKUS_BANNER_ENABLED 设置为 false 来禁用banner 。 此外,用户可以将banner文件放在 src/main/resources 中并在 application.properties 中配置 quarkus.banner.path=name-of-file 来定制banner。

11. 下一步

本指南介绍了如何使用 Quarkus 创建应用程序。然而,还有更多。 我们建议使用 构建本机可执行指南 继续学习,在这里您将学习如何创建本机可执行文件并将其打包到容器中。 如果您对响应式感兴趣,我们建议您使用 响应式入门指南,在这里您可以看到如何使用 Quarkus 实现响应式应用程序。

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

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

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

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

  • 其它

quarkus.pro 是基于 quarkus.io 的非官方中文翻译站 ,最后更新 2020/04 。
沪ICP备19006215号-8
QQ交流群:1055930959
微信群: