编辑此页面

扩展能力

Quarkus 扩展可能提供某些能力,并且需要应用程序中的其他扩展提供某些能力才能正常运行。

能力代表一种技术方面,例如,它可以是某种功能的实现、合同或规范。每个能力都有一个名称,该名称应遵循 Java 包命名约定,例如 io.quarkus.rest

能力承诺和要求在 Quarkus 扩展描述符中描述 - 运行时扩展 JAR 工件的 META-INF/quarkus-extension.properties 条目。

在应用程序中只允许任何给定能力的单个提供者。如果检测到某个能力的多个提供者,应用程序构建将失败并显示相应的错误消息。

如果一个扩展需要某种能力,那么在应用程序依赖项中必须有另一个扩展提供该能力,否则构建将失败并显示相应的错误消息。

在构建时,在应用程序中找到的所有能力将聚合到 io.quarkus.deployment.Capabilities 构建项的实例中,扩展构建步骤可以注入该实例以检查给定的能力是否可用。

声明能力

生成扩展描述符的 quarkus-extension-maven-plugin:extension-descriptor Maven 目标和 extensionDescriptor Gradle 任务允许以以下方式配置提供和所需的能力

Maven
<plugin>
    <groupId>io.quarkus</groupId>
    <artifactId>quarkus-extension-maven-plugin</artifactId>
    <configuration>
        <capabilities>
            <provides>io.quarkus.hibernate.orm</provides> (1)
            <requires>io.quarkus.agroal</requires> (2)
        </capabilities>
    </configuration>
</plugin>
1 该扩展提供 io.quarkus.hibernate.orm 能力(允许有多个 provides 元素)
2 该扩展需要提供 io.quarkus.agroal 能力才能正常运行(允许有多个 requires 元素)
Gradle (Groovy DSL)
quarkusExtension {
    capabilities {
        provides 'io.quarkus.rest' (1)
        requires 'io.quarkus.resteasy' (2)
    }
}
1 该扩展提供 io.quarkus.hibernate.orm 能力(允许有多个 provides 元素)
2 该扩展需要提供 io.quarkus.agroal 能力才能正常运行(允许有多个 requires 元素)
Gradle 扩展插件仍处于实验阶段,将来可能会发生变化。
Gradle (Kotlin DSL)
quarkusExtension {
    capabilities {
        provides("io.quarkus.rest") (1)
        requires("io.quarkus.resteasy") (2)
    }
}
1 该扩展提供 io.quarkus.hibernate.orm 能力(允许有多个 provides 元素)
2 该扩展需要提供 io.quarkus.agroal 能力才能正常运行(允许有多个 requires 元素)
Gradle 扩展插件仍处于实验阶段,将来可能会发生变化。

有条件的能力承诺和要求

只有在满足特定条件的情况下,才能提供或要求某种能力,例如,如果启用了某个配置选项或基于某些其他条件。以下是如何配置有条件的能力承诺

Maven
<plugin>
    <groupId>io.quarkus</groupId>
    <artifactId>quarkus-extension-maven-plugin</artifactId>
    <configuration>
        <capabilities>
            <providesIf> (1)
                <positive>io.quarkus.container.image.openshift.deployment.OpenshiftBuild</positive> (2)
                <name>io.quarkus.container.image.openshift</name> (3)
            </providesIf>
        </capabilities>
    </configuration>
</plugin>
1 有条件的能力声明
2 必须由实现 java.util.function.BooleanSupplier 的类解析为 true 的条件
3 提供的能力名称
providesIf 允许列出多个 <positive> 以及 <negative> 元素。

也支持相应的 requiresIf 元素。

Gradle (Groovy DSL)
quarkusExtension {
    capabilities {
        provides 'io.quarkus.container.image.openshift' onlyIf ['io.quarkus.container.image.openshift.deployment.OpenshiftBuild'] (1)
    }
}
1 必须由实现 java.util.function.BooleanSupplier 的类解析为 true 的条件
也可以指定 onlyIfNot 条件。也可以为所需的能力设置条件。
Gradle (Kotlin DSL)
quarkusExtension {
    capabilities {
        provides("io.quarkus.container.image.openshift").onlyIf(["io.quarkus.container.image.openshift.deployment.OpenshiftBuild"]) (1)
    }
}
1 必须由实现 java.util.function.BooleanSupplier 的类解析为 true 的条件
也可以指定 onlyIfNot 条件。. 也可以为所需的能力设置条件。

在这种情况下,io.quarkus.container.image.openshift.deployment.OpenshiftBuild 应包含在扩展部署依赖项之一中,并实现 java.util.function.BooleanSupplier。在构建时,Quarkus 引导程序将创建它的一个实例,并且只有当它的 getAsBoolean() 方法返回 true 时才注册 io.quarkus.container.image.openshift 能力。

OpenshiftBuild 的实现可能如下所示

import java.util.function.BooleanSupplier;

import io.quarkus.container.image.deployment.ContainerImageConfig;

public class OpenshiftBuild implements BooleanSupplier {

    private ContainerImageConfig containerImageConfig;

    OpenshiftBuild(ContainerImageConfig containerImageConfig) {
        this.containerImageConfig = containerImageConfig;
    }

    @Override
    public boolean getAsBoolean() {
        return containerImageConfig.builder.map(b -> b.equals(OpenshiftProcessor.OPENSHIFT)).orElse(true);
    }
}

CapabilityBuildItem

每个提供的能力将在构建时用 io.quarkus.deployment.builditem.CapabilityBuildItem 的实例表示。理论上,`CapabilityBuildItem` 可以由扩展构建步骤直接生成,绕过扩展描述符中的相应声明。但是,除非有非常好的理由不在描述符中声明能力,否则应避免这种提供能力的方式。

从扩展构建步骤生成的能力不适用于 Quarkus 开发工具。因此,在项目创建期间或向项目添加新扩展时,无法将此类能力纳入分析扩展兼容性的考虑范围。

查询能力

在应用程序中找到的所有能力将在构建期间聚合到 io.quarkus.deployment.Capabilities 构建项的实例中,扩展构建步骤可以注入该实例以检查是否存在某种能力。例如

    @BuildStep
    HealthBuildItem addHealthCheck(Capabilities capabilities, DataSourcesBuildTimeConfig dataSourcesBuildTimeConfig) {
        if (capabilities.isPresent(Capability.SMALLRYE_HEALTH)) {
            return new HealthBuildItem("io.quarkus.agroal.runtime.health.DataSourceHealthCheck",
                    dataSourcesBuildTimeConfig.healthEnabled);
        } else {
            return null;
        }
    }

能力前缀

像能力名称一样,能力前缀是一个以点分隔的字符串,它由第一个能力名称元素或从第一个开始的能力名称元素的点分隔序列组成。例如,对于能力 io.quarkus.resteasy.json.jackson,将注册以下前缀

  • io

  • io.quarkus

  • io.quarkus.resteasy

  • io.quarkus.resteasy.json

Capabilities.isCapabilityWithPrefixPresent(prefix) 可用于检查是否存在具有给定前缀的能力。

鉴于在应用程序中只允许给定能力的单个提供者,能力前缀允许表达不同但有些相关的能力之间的某种共同方面。例如,可能有扩展提供以下能力

  • io.quarkus.resteasy.json.jackson

  • io.quarkus.resteasy.json.jackson.client

  • io.quarkus.resteasy.json.jsonb

  • io.quarkus.resteasy.json.jsonb.client

在应用程序中包含这些扩展中的任何一个都将启用 RESTEasy JSON 序列化器。如果构建步骤需要检查是否已在应用程序中启用 RESTEasy JSON 序列化器,而不是检查是否存在这些能力中的任何一个,它可以简单地检查是否存在带有前缀 io.quarkus.resteasy.json 的扩展。

相关内容