命令模式简介

是否曾想过从命令行应用程序中使用 Quarkus 强大的 API 和完整的特性集?

您是否需要偶尔运行一个计划的批处理作业,而不想将其嵌入到您的主 Quarkus 构建服务中?

3xwzsh

到目前为止,Quarkus 一直用于编写通过端点运行的应用程序,即通过 HTTP 运行的长时间运行的 Web 服务器,或者在无服务器环境中的短时函数。

在 Quarkus 1.4 中,命令模式允许您编写不带端点即可运行并可选择立即退出的应用程序。

这使得您可以使用 Quarkus 来编写一种全新的应用程序风格——例如命令行客户端 (CLI)、批处理脚本、控制台应用程序等。

如何使用

下面是一个简单的 GreetingMain 类,它使用了我们所有快速入门示例中的传统 GreetingService

import io.quarkus.runtime.QuarkusApplication;
import io.quarkus.runtime.annotations.QuarkusMain;

@QuarkusMain    (1)
public class GreetingMain implements QuarkusApplication {
  @Inject (2)
  GreetingService service;

  @Override
  public int run(String... args) throws Exception {   (3)

    if (args.length>0) {
      System.out.println(service.greeting(arg[0]));
    } else {
      System.out.println(service.greeting(""));
    }

    return 0;
 }
}
1 @QuarkusMain 注释告诉 Quarkus 这是主入口点。
2 一旦 Quarkus 启动,run 方法就会被调用,并在完成后应用程序停止。如果您想访问请求作用域的 bean,可以在 run 方法上使用 @ActivateRequestContext 注释。这对于使用例如 Hibernate Panache Entity bean 查询方法来编写或重用您现有的业务逻辑非常有用。

您可以将此添加到 GreetingMain.java 中,编译为 .jar 或完全原生(使用 mvnw package -Dnative),运行时您会得到类似以下输出:

 ./target/getting-started-command-mode-1.0-SNAPSHOT-runner commando
__  ____  __  _____   ___  __ ____  ______
 --/ __ \/ / / / _ | / _ \/ //_/ / / / __/
 -/ /_/ / /_/ / __ |/ , _/ ,< / /_/ /\ \
--\___\_\____/_/ |_/_/|_/_/|_|\____/___/
2020-04-25 00:14:38,999 INFO  [io.quarkus] (main) getting-started-command-mode 1.0-SNAPSHOT (powered by Quarkus 999-SNAPSHOT) started in 0.005s.
2020-04-25 00:14:38,999 INFO  [io.quarkus] (main) Profile prod activated.
2020-04-25 00:14:38,999 INFO  [io.quarkus] (main) Installed features: [cdi]
hello commando
2020-04-25 00:14:38,999 INFO  [io.quarkus] (main) getting-started-command-mode stopped in 0.000s

干净的输出

在使用 CLI 时,默认的控制台日志输出可能会非常冗长。目前,关闭它的最佳方法是设置以下属性:

quarkus.log.level=SEVERE
quarkus.hibernate-orm.log.sql=false
quarkus.banner.enabled=false

这些属性可以通过在自定义配置文件中添加 %cli. 前缀来设置,该配置文件称为 cli

这存在一些问题,在 issue #8871 中正在讨论可能的解决方案。

开发模式

命令模式与 quarkus:dev(即开发模式)配合使用。

当您使用 mvn quarkus:dev 运行时,可以添加 -Dquarkus.args=yourvalue 作为您想传递给命令行的参数。

quarkusargs 将会按空格分割,并会正确处理转义引号。因此,使用 mvn quarkus:dev -Dquarkus.args="foo bar \"baz qux\"" 运行应用程序,启动后结束时的样子如下:

foo
bar
baz qux
Quarkus application exited with code 0
Press Enter to restart or Ctrl + C to quit

您现在可以按 Enter 键多次强制重新运行,如果您编辑了源代码,按 Enter 键将触发构建,然后以极低的开销重新启动。

主方法

作为通过 @QuarkusMain 注释的类添加命令模式的一部分,您现在可以拥有自己的 static void main() 方法。下面的代码片段是使用 main 方法运行 Quarkus 的最低要求。

static void main(String ...args) {
    Quarkus.run(args);
}

与上面的 @QuarksMain 类一起使用将是这样的:

static void main(String ...args) {
    Quarkus.run(GreetingMain.class, args);
}

就是这样。这不仅允许您自定义 Quarkus 应用程序的启动/停止,而且还实现了许多人所期望的功能:能够直接从 IDE 启动/调试 Quarkus 应用程序。

您可以在 command-mode quickstart 中看到这些类的完整工作示例。

最小 CLI 应用

值得注意的是,您的 CLI 应用程序仍然可以提供一个端点——事实上,在默认应用程序中,我们刚刚创建的 REST 端点仍在启动和运行。您只是没有注意到它。Quarkus 就是这么快。

如果您确实需要一个最小化的扩展,请从您的 pom.xml 中删除 quarkus-resteasy 扩展,而是放入 arc

然后,除了您的 Quarkus 主类之外,将不再运行任何其他内容。

下一步是什么?

您说了算!您想用 Quarkus 做什么命令行应用?

目前我们很享受编写 CLI,但有多少人会加入我们呢!

请在 https://github.com/quarkusio/quarkus/issues 上告诉我们您的想法。