编辑此页面

平台

Quarkus 扩展生态系统由社区(包括 Quarkus 核心开发团队)开发和维护的 Quarkus 扩展组成。虽然 Quarkus 生态系统(有时也称为“Quarkus 世界”)包括所有已开发的 Quarkus 扩展,但也有一个 Quarkus 平台的概念。

Quarkus 平台

Quarkus 平台的基本承诺是,平台所包含的任何 Quarkus 扩展的组合都可以在同一个应用程序中使用,而不会相互冲突。每个创建其 Quarkus 平台的组织都可以建立自己的标准,以将扩展接受到平台中,并保证接受的扩展之间的兼容性。

Quarkus 平台构件

每个 Quarkus 平台都由几个构件定义。

Quarkus 平台 BOM

每个 Quarkus 平台都应该提供一个 Maven BOM 构件,它

  • 导入选定版本的 io.quarkus:quarkus-bom(平台 BOM 最终可能会被展平,但它必须基于 io.quarkus:quarkus-bom 的某个版本)

  • 包含平台所包含的所有 Quarkus 扩展构件(运行时和部署构件)

  • 包含所有必要的第三方构件,这些构件对齐平台扩展的传递依赖版本,以保证它们之间的兼容性

  • 包含 平台 JSON 描述符构件

  • 可能包含 平台配置属性构件

想要包含来自 Quarkus 平台的扩展的 Quarkus 应用程序将导入 Quarkus 平台 BOM。

Quarkus 平台描述符

Quarkus 平台描述符是一个 JSON 构件,它向 Quarkus 工具提供有关平台及其扩展的信息。例如,https://code.quarkus.io/ 和 Quarkus 命令行工具查询此描述符以列出、添加和删除用户请求的项目中的扩展。此构件也用作 Quarkus 平台标识符。当 Quarkus 工具需要识别项目中使用的 Quarkus 平台时,它们将分析项目的依赖版本约束(Maven 术语中有效管理依赖项列表),从中查找平台描述符构件。 鉴于平台描述符包含在 Quarkus 平台 BOM 中,每个 Quarkus 应用程序都将从导入的平台 BOM 中继承平台描述符构件作为依赖版本约束(Maven 术语中的管理依赖项)。

为了能够轻松识别项目依赖约束中的 Quarkus 平台描述符,平台描述符 Maven 构件坐标应遵循以下命名约定

  • 描述符构件的 groupId 应与相应 Quarkus 平台 BOM 的 groupId 匹配;

  • 描述符构件的 artifactId 应为相应 Quarkus 平台 BOM 的 artifactId,并带有 -quarkus-platform-descriptor 后缀;

  • 描述符构件的 classifier 应与相应 Quarkus 平台 BOM 的 version 匹配;

  • 描述符构件的 type 应为 json

  • 描述符构件的 version 应与相应 Quarkus 平台 BOM 的 version 匹配。

作为字符串,它看起来像 <platform-bom-groupId>:<platform-bom-artifactId>-quarkus-platform-descriptor:<platform-version>:json:<platform-version>

例如,Quarkus BOM io.quarkus.platform:quarkus-bom::pom:1.2.3 的描述符坐标将为 io.quarkus.platform:quarkus-bom-quarkus-platform-descriptor:1.2.3:json:1.2.3。对于使用 BOM org.acme:acme-bom::pom:555 定义的自定义 Quarkus 平台,它将为 org.acme:acme-bom-quarkus-platform-descriptor:555:json:555

与平台版本匹配的分类器乍一看可能令人困惑。 但这就是将描述符变成平台真正“指纹”的原因。 在 Maven 和 Gradle 中,依赖版本约束(或管理依赖项)的有效集是通过合并所有导入的 BOM 以及当前项目及其父项中单独指定的版本约束获得的。 构件 classifier 是依赖 ID 的一部分,可以表示为 groupId:artifactId:classifier:type。 这意味着如果一个项目导入了几个 BOM,例如 org.apple:apple-bom::pom:1.0org.orange:orange-bom::pom:1.0,并且这两个 BOM 中的每一个都导入了不同的版本 io.quarkus.platform:quarkus-bom::pom,Quarkus 工具将能够检测到这一事实并使用户意识到它,因为它**可能**不是一个安全的组合。 如果描述符构件不包含包含平台版本的分类器,那么这些工具将无法检测到同一项目中同一平台的不同版本的潜在不兼容混合。

平台描述符通常使用 Maven 插件生成,例如

<plugin>
  <groupId>io.quarkus</groupId>
  <artifactId>quarkus-platform-descriptor-json-plugin</artifactId>
  <version>${quarkus.version}</version> (1)
  <executions>
    <execution>
      <phase>process-resources</phase>
      <goals>
        <goal>generate-extensions-json</goal> (2)
      </goals>
    </execution>
  </executions>
  <configuration>
    <bomGroupId>${quarkus.platform.group-id}</bomGroupId> (3)
    <bomArtifactId>${quarkus.platform.artifact-id}</bomArtifactId> (4)
    <bomVersion>${quarkus.platform.version}</bomVersion> (5)
    <overridesFile>${overridesfile}</overridesFile> (6)
    <resolveDependencyManagement>true</resolveDependencyManagement> (7)
  </configuration>
</plugin>
1 quarkus-platform-descriptor-json-plugin 的版本
2 generate-extensions-json 是生成平台描述符的目标
3 平台 BOM 的 groupId
4 平台 BOM 的 artifactId
5 平台 BOM 的 version
6 此参数是可选的,它允许覆盖从平台描述符生成的每个运行时扩展构件中找到的 Quarkus 扩展描述符中的一些元数据
7 此参数也是可选的,默认为 false。 如果平台 BOM **未生成**且**未展平**,则必须将其设置为 true。 例如 io.quarkus:quarkus-bom 就是这种情况。

Quarkus 平台属性

Quarkus 平台可以为其某些配置选项提供自己的默认值。

Quarkus 正在使用 SmallRye Config 来连接应用程序配置。 Quarkus 平台可以用作配置源层次结构中的另一个配置源,该层次结构由应用程序的 application.properties 主导。

为了提供平台特定的默认值,平台需要在其 BOM 中包含一个属性构件的依赖版本约束,该构件的坐标遵循以下命名约定

  • 属性构件的 groupId 应与相应 Quarkus 平台 BOM 的 groupId 匹配;

  • 属性构件的 artifactId 应为相应 Quarkus 平台 BOM 的 artifactId,并带有 -quarkus-platform-properties 后缀;

  • 描述符构件的 classifier 应留空/空;

  • 描述符构件的 type 应为 properties

  • 描述符构件的 version 应与相应 Quarkus 平台 BOM 的 version 匹配。

属性构件本身应为一个传统的 properties 文件,该文件将被加载到 java.util.Properties 类的实例中。

此时,平台属性仅允许为一组受限的配置选项提供默认值。 平台属性文件中的属性名称必须以 platform. 后缀为前缀。

想要使其配置选项具有平台特定性的扩展开发人员应将其默认值设置为以 platform. 后缀开头的属性。 这是一个例子

package io.quarkus.deployment.pkg;

@ConfigRoot(phase = ConfigPhase.BUILD_TIME)
@ConfigMapping(prefix = "quarkus")
public interface NativeConfig {

    /**
     * The docker image to use to do the image build
     */
    @WithDefault("${platform.quarkus.native.builder-image}")
    String builderImage();
}

在这种情况下,quarkus.native.builder-image 的默认值将由平台提供。 用户仍然可以在其 application.properties 中为 quarkus.native.builder-image 设置所需的值,当然。 但是,如果用户没有自定义它,默认值将来自平台属性。 上述示例的平台属性文件将包含

platform.quarkus.native.builder-image=quay.io/quarkus/ubi9-quarkus-mandrel-builder-image:jdk-21

从 Quarkus 3.19+ 开始,用于构建本机可执行文件的构建器映像基于 UBI 9。 这意味着容器构建生成的本机可执行文件也将基于 UBI 9。 因此,如果您计划构建容器,请确保 Dockerfile 中的基础映像与 UBI 9 兼容。 本机可执行文件将无法在 UBI 8 基础映像上运行。

例如,要切换回 UBI8 构建器映像,您可以使用

platform.quarkus.native.builder-image=quay.io/quarkus/ubi-quarkus-mandrel-builder-image:jdk-21

您可以在此处查看 UBI8 的可用标签,在此处 (UBI 9)) 查看 UBI9 的可用标签

还有一个 Maven 插件目标可以验证平台属性内容及其构件坐标,并检查平台属性构件是否出现在平台的 BOM 中。 这是一个示例插件配置

<plugin>
  <groupId>io.quarkus</groupId>
  <artifactId>quarkus-platform-descriptor-json-plugin</artifactId>
  <version>${quarkus.version}</version>
  <executions>
    <execution>
      <phase>process-resources</phase>
      <goals>
        <goal>platform-properties</goal>
      </goals>
    </execution>
  </executions>
</plugin>

合并 Quarkus 平台属性

如果应用程序导入多个 Quarkus 平台,并且这些平台包含自己的平台属性构件,则这些平台属性构件的内容将被合并以形成一组将用于应用程序构建的属性。 合并属性构件的顺序将对应于它们在应用程序依赖版本约束列表中的出现顺序(在 Maven 术语中,这将对应于应用程序的管理依赖项的有效列表,即展平的 managedDependencies POM 部分)。

在应用程序的依赖约束中,较早找到的属性构件的内容将支配以后找到的属性构件!

这意味着如果平台需要覆盖在其所基于的平台中定义的某个属性值,它将需要在导入基本平台之前将其平台属性构件包含在其 BOM 的 managedDependencies 部分中。

例如,让我们假设 org.acme:acme-quarkus-bom 平台通过导入其 BOM 来扩展 io.quarkus:quarkus-bom 平台。 如果 org.acme:acme-quarkus-bom 平台要覆盖 io.quarkus:quarkus-bom 中包含的 io.quarkus:quarkus-bom-quarkus-platform-properties 中定义的某些属性,则 org.acme:acme-quarkus-bom 必须编写为

  <!-- skipped content -->

  <artifactId>acme-quarkus-bom</artifactId>
  <name>Acme - Quarkus - BOM</name>
  <packaging>pom</packaging>

  <dependencyManagement>
    <dependencies>
      <!-- Acme Quarkus platform properties -->
      <dependency>
        <groupId>org.acme</groupId>
        <artifactId>acme-quarkus-bom-quarkus-platform-properties</artifactId>
        <type>properties</type>
        <version>${project.version}</version>
      </dependency>

      <!-- The base Quarkus BOM -->
      <dependency>
        <groupId>io.quarkus</groupId>
        <artifactId>quarkus-bom</artifactId>
        <version>${quarkus.version}</version>
        <type>pom</type>
        <scope>import</scope>
      </dependency>

  <!-- skipped content -->

这样,org.acme:acme-quarkus-bom 平台属性将出现在 io.quarkus:quarkus-bom 属性提供的属性之前,因此将在构建时占主导地位。

相关内容