

这是 AWS CDK v2 开发者指南。旧版 CDK v1 于 2022 年 6 月 1 日进入维护阶段，并于 2023 年 6 月 1 日终止支持。

本文属于机器翻译版本。若本译文内容与英语原文存在差异，则一律以英文原文为准。

# 在 Java 中使用 AWS CDK
<a name="work-with-cdk-java"></a>

Java 是 AWS CDK 完全支持的客户端语言，被认为是稳定的。你可以使用熟悉的工具用 Java 开发 AWS CDK 应用程序，包括 JDK（甲骨文的，或者像 Amazon Corretto 这样的 OpenJDK 发行版）和 Apache Maven。

 AWS CDK 支持 Java 8 及更高版本。但是，我们建议您尽量使用最新版本，因为该语言的更高版本包含了特别便于开发 AWS CDK 应用程序的改进。例如，Java 9 引入了该`Map.of()`方法（一种声明哈希映射的便捷方法，该哈希映射将在中 TypeScript写成对象文字）。Java 10 使用 `var` 关键字引入了本地类型推断。

**注意**  
本《开发人员指南》中的大多数代码示例都采用 Java 8。有几个示例使用了 `Map.of()`；这些示例包含注释，指出它们需要使用 Java 9。

您可以使用任何文本编辑器或可以读取 Maven 项目的 Java IDE 来处理 AWS CDK 应用程序。我们在本指南中提供了 [Eclipse](https://www.eclipse.org/downloads/) 提示，但是 IntelliJ IDEA 等 IDEs 可以导入 Maven 项目 NetBeans，并且可以用来在 Java 中开发 AWS CDK 应用程序。

可以用 Jvm 托管的语言（例如 AWS Kotlin、Groovy、Clojure 或 Scala）以外的其他语言编写 CDK 应用程序，但这种体验可能不是特别习惯，我们无法为这些语言提供任何支持。

## 开始使用 Java
<a name="java-prerequisites"></a>

要使用 AWS CDK，您必须拥有 AWS 账户和凭证，并已安装 Node.js 和 AWS CDK 工具包。请参阅 [AWS CDK 入门](getting-started.md)。

Java AWS CDK 应用程序需要 Java 8 (v1.8) 或更高版本。我们推荐 [Amazon Corretto](https://aws.amazon.com/corretto/)，但您可以使用任何 OpenJDK 发行版或 [Oracle JDK](https://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html)。您还需要 [Apache Maven](https://maven.apache.org/download.cgi) 3.5 或更高版本。你也可以使用诸如 Gradle 之类的工具，但是 AWS CDK 工具包生成的应用程序框架是 Maven 项目。

**注意**  
第三方语言弃用：语言版本仅在供应商或社区共享其 EOL（生命周期终止）之前才受支持，如有更改，会另行通知。

## 创建项目
<a name="java-newproject"></a>

您可以通过在空目录`cdk init`中调用来创建新的 AWS CDK 项目。使用 `--language` 选项并指定 `java`：

```
$ mkdir my-project
$ cd my-project
$ cdk init app --language java
```

 `cdk init` 使用项目文件夹的名称来命名项目的各种元素，包括类、子文件夹和文件。文件夹名称中的连字符都将转换为下划线。但是，名称应遵循 Java 标识符的形式；例如，名称不应以数字开头，也不应包含空格。

由此生成的项目包含对 `software.amazon.awscdk` Maven 包的引用。该包及其依赖项由 Maven 自动进行安装。

如果您使用的是 IDE，现在可以打开或导入项目了。例如，在 Eclipse 中，依次选择**文件** > **导入** > **Maven** > **现有的 Maven 项目**。确保将项目设置设为使用 Java 8（1.8）。

## 管理 AWS 构造库模块
<a name="java-managemodules"></a>

使用 Maven 安装组`software.amazon.awscdk`中的 AWS 构造库软件包。大多数构造都在构件 `aws-cdk-lib` 中，默认情况下，该构件会添加到新的 Java 项目中。仍在开发更高级别 CDK 支持的服务的模块位于单独的 “实验性” 包中，并以其服务名称的简短版本（无或 AWS Amazon 前缀）命名。[搜索 Maven 中央存储库](https://search.maven.org/search?q=software.amazon.awscdk)以查找所有 AWS CDK 和 C AWS onstruct Module 库的名称。

**注意**  
[CDK API Reference 的 Java 版本](https://docs.aws.amazon.com/cdk/api/v2/java/index.html)也显示了包名称。

某些服务的 AWS 构造库支持位于多个命名空间中。例如，Amazon Route 53 将其功能分为 `software.amazon.awscdk.route53`、`route53-patterns`、`route53resolver` 和 `route53-targets`。

主要 AWS CDK 包以 Java 代码导入为。`software.amazon.awscdk` AWS 构造库中各种服务的模块位于其下，其命名`software.amazon.awscdk.services`与它们的 Maven 包名称类似。例如，Amazon S3 模块的命名空间为 `software.amazon.awscdk.services.s3`。

我们建议您为每个 Java 源文件中使用的每个 AWS 构造库类编写单独的 Java `import` 语句，并避免导入通配符。您始终使用类型的完全限定名称（包括其命名空间），而无需使用 `import` 语句。

如果您的应用程序依赖于实验包，请编辑项目的 `pom.xml` 并在 `<dependencies>` 容器中添加新的 `<dependency>` 元素。例如，以下`<dependency>`元素指定了 CodeStar 实验构造库模块：

```
<dependency>
    <groupId>software.amazon.awscdk</groupId>
    <artifactId>codestar-alpha</artifactId>
    <version>2.0.0-alpha.10</version>
</dependency>
```

**提示**  
如果您使用 Java IDE，其可能具备管理 Maven 依赖项的功能。但是，除非您完全确定 IDE 的功能与您手动操作的功能相匹配，否则我们建议您直接编辑 `pom.xml`。

## 在 Java 中管理依赖项
<a name="work-with-cdk-java-dependencies"></a>

在 Java 中，使用 Maven 在 `pom.xml` 中指定依赖项并进行安装。`<dependencies>` 容器包含每个包的 `<dependency>` 元素。以下是常见的 CDK Java 应用程序 `pom.xml` 的其中一部分。

```
<dependencies>
    <dependency>
        <groupId>software.amazon.awscdk</groupId>
        <artifactId>aws-cdk-lib</artifactId>
        <version>2.14.0</version>
    </dependency>
    <dependency>
        <groupId>software.amazon.awscdk</groupId>
        <artifactId>appsync-alpha</artifactId>
        <version>2.10.0-alpha.0</version>
    </dependency>
</dependencies>
```

**提示**  
许多 Java IDEs 都集成了 Maven 支持和可视化`pom.xml`编辑器，您可能会发现它们便于管理依赖关系。

Maven 不支持依赖项锁定。尽管可以在 `pom.xml` 中指定版本范围，但我们建议您始终使用确切版本，以保持构建的可重复性。

Maven 会自动安装传递依赖项，但每个包只能安装一个副本。已选择 POM 树中指定的最高版本；应用程序对安装哪个版本的软件包始终拥有最终决定权。

每当您构建（`mvn compile`）或打包（`mvn package`）项目时，Maven 都会自动安装或更新您的依赖项。每次运行 CDK Toolkit 时，其都会自动执行此操作，因此通常无需手动调用 Maven。

## AWS Java 中的 CDK 成语
<a name="java-cdk-idioms"></a>

### Props
<a name="java-props"></a>

所有 C AWS onstruct Library 类都使用三个参数进行实例化：定义构造的*作用域*（构造树中的父级）、*id* 和 *props*（构造函数用来配置其创建的资源的一 key/value 组对）。其他类和方法也使用“属性捆绑包”模式作为参数。

在 Java 中，props 是使用[生成器模式](https://en.wikipedia.org/wiki/Builder_pattern)来表示的。每种构造类型都有相应的 props 类型；例如，`Bucket` 构造（表示 Amazon S3 存储桶）将 `BucketProps` 的实例作为其 props。

该`BucketProps`类（就像每个 Constru AWS ct Library 道具类一样）有一个名`Builder`为的内部类。`BucketProps.Builder` 类型提供了设置 `BucketProps` 实例各种属性的方法。每个方法都会返回 `Builder` 实例，因此可以链接方法调用来设置多个属性。在链的末端，调用 `build()` 来实际生成 `BucketProps` 对象。

```
Bucket bucket = new Bucket(this, "amzn-s3-demo-bucket", new BucketProps.Builder()
                           .versioned(true)
                           .encryption(BucketEncryption.KMS_MANAGED)
                           .build());
```

构造和其他以类似 props 的对象作为最终参数的类提供了一种快捷方式。该类有自己的 `Builder`，可以一步将类以及其 props 对象进行实例化。这样，您就不必明确实例化（例如）`BucketProps` 和 `Bucket`，也不需要导入 props 类型。

```
Bucket bucket = Bucket.Builder.create(this, "amzn-s3-demo-bucket")
                           .versioned(true)
                           .encryption(BucketEncryption.KMS_MANAGED)
                           .build();
```

从现有构造派生自己的构造时，可能需要接受其他属性。我们建议您遵循这些构建器模式。然而，这并不是对构造类进行子类化那么简单。您必须自己提供这两个新 `Builder` 类的移动部件。您可能更愿意只让您的构造接受一个或多个额外参数。如果参数是可选的，则应提供额外的构造函数。

### 通用结构
<a name="java-generic-structures"></a>

在某些情况下 APIs， AWS CDK 使用 JavaScript 数组或非类型化对象作为方法的输入。（例如， AWS CodeBuild请参阅[https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_codebuild.BuildSpec.html#static-fromwbrobjectvalue](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_codebuild.BuildSpec.html#static-fromwbrobjectvalue)的方法。） 在 Java 中，这些对象表示为 `java.util.Map<String, Object>`。在值都为字符串的情况下，则可以使用 `Map<String, String>`。

与其他一些语言不同，Java 不提供为此类容器编写字面量的方法。在 Java 9 及更高版本中，您可以使用 [https://docs.oracle.com/javase/9/docs/api/java/util/Map.html#ofEntries-java.util.Map.Entry…​-](https://docs.oracle.com/javase/9/docs/api/java/util/Map.html#ofEntries-java.util.Map.Entry…​-) 方便地定义映射，这些映射最多包含十个条目且与其中一个调用内联。

```
java.util.Map.of(
    "base-directory", "dist",
    "files", "LambdaStack.template.json"
 )
```

要创建包含十个以上条目的映射，请使用 [https://docs.oracle.com/javase/9/docs/api/java/util/Map.html#ofEntries-java.util.Map.Entry…​-](https://docs.oracle.com/javase/9/docs/api/java/util/Map.html#ofEntries-java.util.Map.Entry…​-)。

如果您使用的是 Java 8，则可以提供与这些方法类似的自己的方法。

JavaScript 数组在 Java `List<String>` 中以`List<Object>`或的形式表示。`java.util.Arrays.asList` 方法对于定义短 `List` 来说很方便。

```
List<String> cmds = Arrays.asList("cd lambda", "npm install", "npm install typescript")
```

### 缺失值
<a name="java-missing-values"></a>

在 Java 中，道具等 AWS CDK 对象中的缺失值用表示。`null`您必须明确测试任何可能为 `null` 的值，以确保其包含一个值，然后才能用其进行操作。Java 不像其他一些语言有“语法糖”来帮助处理 null 值。你可能会发现 Apac ObjectUtil h [https://commons.apache.org/proper/commons-lang/apidocs/org/apache/commons/lang3/ObjectUtils.html#defaultIfNull-T-T-](https://commons.apache.org/proper/commons-lang/apidocs/org/apache/commons/lang3/ObjectUtils.html#defaultIfNull-T-T-)e 在某些情况下[https://commons.apache.org/proper/commons-lang/apidocs/org/apache/commons/lang3/ObjectUtils.html#firstNonNull-T…​-](https://commons.apache.org/proper/commons-lang/apidocs/org/apache/commons/lang3/ObjectUtils.html#firstNonNull-T…​-)很有用。或者，也可以编写自己的静态辅助方法，以便更容易处理潜在的 null 值并提高代码的可读性。

## 构建和运行 CDK 应用程序
<a name="java-running"></a>

 AWS CDK 会在运行您的应用程序之前自动对其进行编译。但是，手动构建应用程序以检查错误并运行测试可能会很有用。您可以在 IDE 中执行此操作（例如，在 Eclipse 中按 Control-B），也可以在项目的根目录中在命令提示符下发出 `mvn compile` 命令来执行此操作。

在命令提示符下运行 `mvn test` 命令来运行您编写的所有测试。