Conditional Extension Dependencies

Quarkus 扩展依赖项通常按项目在项目构建文件中与任何其他项目依赖项不同的方式进行配置,例如 Maven pom.xml 或 Gradle 构建脚本。但是,Maven 和 Gradle 还不支持开箱即用的依赖项类型。我们这里提到的“条件依赖项”就是一个例子。

Conditional Dependencies

条件依赖性的思想是,只有在满足特定条件时才必须激活此类依赖项。如果条件不满足,则 must not 依赖项将被激活。在这方面,条件依赖项可以归类为可选项,即它们可能出现在项目依赖项的结果集中,也可能不出现。

在哪些情况下条件依赖项可能有用?一个典型的例子是一个组件,当其所有必需依赖项都可用时,它应该 only 激活。如果组件的一个或多个必需依赖项不可用,组件不应失败,而应不激活。

Quarkus Conditional Extension Dependencies

Quarkus 支持条件扩展依赖项。即一个 Quarkus 扩展可以通过其他 Quarkus 扩展声明一个或多个条件依赖项。不支持不属于扩展程序工件的条件依赖项。

让我们以以下场景为例:quarkus-extension-aquarkus-extension-b 有一个可选依赖项,它应该仅在其依赖项(直接或传递)中找到 quarkus-extension-c 时才包含在 Quarkus 应用程序中。换句话说,quarkus-extension-c 的存在是条件,如果满足,则在构建 Quarkus 应用程序期间会启用 quarkus-extension-b

触发扩展激活的条件是在扩展程序的描述符中配置的,该描述符作为 META-INF/quarkus-extension.properties 包含在扩展程序的运行时工件中。由于扩展符描述符是由 Quarkus 插件在扩展符构建时生成的,因此扩展符开发人员可以添加以下配置来表示扩展符激活所必需的条件:

<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">

  <!-- SKIPPED CONTENT -->

  <artifactId>quarkus-extension-b</artifactId> 1

  <!-- SKIPPED CONTENT -->

  <build>
    <plugins>
      <plugin>
        <groupId>io.quarkus</groupId>
        <artifactId>quarkus-extension-maven-plugin</artifactId>
        <version>${quarkus.version}</version>
        <executions>
          <execution>
            <phase>process-resources</phase>
            <goals>
              <goal>extension-descriptor</goal> 2
            </goals>
            <configuration>
              <dependencyCondition> 3
                <artifact>org.acme:quarkus-extension-c</artifact> 4
              </dependencyCondition>
            </configuration>
          </execution>
        </executions>
      </plugin>

  <!-- SKIPPED CONTENT -->
1 运行时 Quarkus 扩展工件 ID,在本示例中为 quarkus-extension-b
2 生成扩展符描述符的目标,每个 Quarkus 运行时扩展符项目都应配置此目标;
3 该扩展符包含在 Quarkus 应用程序中时必须满足的条件配置,表示为应用程序依赖项中必须存在的工件列表;
4 工件的工件键(格式为 groupId:artifactId[:&lt;classifier&gt;:&lt;extension&gt;] ,但通常只是 &lt;groupId&gt;:&lt;artifactId&gt;),为了满足条件,工件必须存在于应用程序依赖项中。

在上面的示例中,条件配置中使用的 artifact 碰巧是一个运行时 Quarkus 扩展工件,但它也可以是任何其他工件。dependencyCondition 的正文中还可以有多个 artifact 元素。

现在,在 quarkus-extension-b 的描述符中有一个依赖项激活条件,其他扩展可以声明对它的条件依赖项。

条件依赖项是在 Quarkus 扩展的运行时工件中配置的。在我们的示例中,quarkus-extension-aquarkus-extension-b 有条件依赖项,可以用两种方式表示。

Declaring a dependency as optional

如果一个扩展在它的描述符中配置了一个依赖条件,其他扩展可以通过简单地向依赖项配置中添加 <optional>true</optional> 来配置对它的条件依赖项。在我们的示例中,它将如下所示:

<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">

  <!-- SKIPPED CONTENT -->

  <artifactId>quarkus-extension-a</artifactId> 1

  <!-- SKIPPED CONTENT -->

  <dependencies>
    <dependency>
      <groupId>org.acme</groupId>
      <artifactId>quarkus-extension-b</artifactId> 2
      <optional>true</optional>
    </dependency>

  <!-- SKIPPED CONTENT -->
1 运行时扩展工件 quarkus-extension-a
2 quarkus-extension-b 的运行时扩展制品上声明一个可选的 Maven 依赖。

通常,对于针对另一个运行时扩展制品依赖的运行时扩展制品依赖,在另一个部署扩展制品上的部署扩展制品依赖必须是对应的。而如果运行时依赖被声明为可选,那么对应的部署依赖 must 也必须被配置为可选。

<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">

  <!-- SKIPPED CONTENT -->

  <artifactId>quarkus-extension-a-deployment</artifactId> 1

  <!-- SKIPPED CONTENT -->

  <dependencies>
    <dependency>
      <groupId>org.acme</groupId>
      <artifactId>quarkus-extension-b-deployment</artifactId> 2
      <optional>true</optional>
    </dependency>

  <!-- SKIPPED CONTENT -->
1 quarkus-extension-a-deployment 的部署扩展制品上
2 声明一个可选的 Maven 依赖在 quarkus-extension-b-deployment 的部署扩展制品上

通常,可选的 Maven 扩展依赖在构建时会被 Quarkus 依赖解析器忽略。然而,在这种情况下,可选依赖 quarkus-extension-b 在扩展描述符中包含一个依赖条件,这将该可选 Maven 依赖转换为一个 Quarkus 条件扩展依赖。

如果 quarkus-extension-b 不是声明为`<optional>true</optional>`,那将会使`quarkus-extension-b`成为 quarkus-extension-a 的必需依赖,并且它的依赖条件将会被忽略。

Declaring a conditional dependency in the Quarkus extension descriptor

条件依赖也可以在 Quarkus 扩展描述符中配置。上面配置的条件依赖可以在`quarkus-extension-a`的扩展描述符中表达为:

<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">

  <!-- SKIPPED CONTENT -->

  <artifactId>quarkus-extension-a</artifactId> 1

  <!-- SKIPPED CONTENT -->

  <build>
    <plugins>
      <plugin>
        <groupId>io.quarkus</groupId>
        <artifactId>quarkus-extension-maven-plugin</artifactId>
        <version>${quarkus.version}</version>
        <executions>
          <execution>
            <phase>process-resources</phase>
            <goals>
              <goal>extension-descriptor</goal> 2
            </goals>
            <configuration>
              <conditionalDependencies> 3
                <extension>org.acme:quarkus-extension-b:${b.version}</extension> 4
              </conditionalDependencies>
            </configuration>
          </execution>
        </executions>
      </plugin>

  <!-- SKIPPED CONTENT -->
1 运行时 Quarkus 扩展的制品 ID,在我们的示例中为 quarkus-extension-a
2 为每个 Quarkus 运行时扩展项目应当配置的生成扩展描述符的目标
3 conditional dependency configuration element
4 其他扩展上的条件依赖的制品坐标。

在这种情况下,Maven 依赖在`pom.xml`中完全不需要。