这是 AWS CDK v2 开发者指南。旧版 CDK v1 于 2022 年 6 月 1 日进入维护阶段,并于 2023 年 6 月 1 日终止支持。
本文属于机器翻译版本。若本译文内容与英语原文存在差异,则一律以英文原文为准。
在 Java 中使用 AWS CDK
Java 是一种 AWS CDK 完全支持且视为稳定的客户端语言。您可以使用熟悉的工具用 Java 开发 AWS CDK 应用程序,包括 JDK(Oracle 或 Amazon Corretto 等 OpenJDK 发行版)和 Apache Maven 等工具。
AWS CDK 支持 Java 8 及更高版本。但是,我们建议您尽量使用最新版本,因为该语言的更高版本包含了一些改进,对于开发 AWS CDK 应用程序特别方便。例如,Java 9 引入了 Map.of() 方法(一种声明 hashmap 的便捷方法,这些 hashmap 将在 TypeScript 中被写为对象文本)。Java 10 使用 var 关键字引入了本地类型推断。
注意
本《开发人员指南》中的大多数代码示例都采用 Java 8。有几个示例使用了 Map.of();这些示例包含注释,指出它们需要使用 Java 9。
您可以使用任何文本编辑器或可以读取 Maven 项目的 Java IDE 来处理您的 AWS CDK 应用程序。我们在本指南中提供了 Eclipse
可以用 Java 以外的 JVM 托管语言(例如 Kotlin、Groovy、Clojure 或 Scala)编写 AWS CDK 应用程序,但这些不是惯用的语言,我们无法为这些语言提供任何支持。
开始使用 Java
要使用 AWS CDK,您必须拥有 AWS 账户和凭证,并已安装 Node.js 和 AWS CDK 工具包。请参阅开始使用 AWS CDK。
Java AWS CDK 应用程序需要 Java 8 (v1.8) 或更高版本。我们推荐 Amazon Corretto
注意
第三方语言弃用:语言版本仅在供应商或社区共享其 EOL(生命周期终止)之前才受支持,如有更改,会另行通知。
创建项目
您可以通过在空目录中调用 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 构造库模块
使用 Maven 来安装 AWS 构造库软件包,这些包位于 software.amazon.awscdk 组中。大多数构造都在构件 aws-cdk-lib 中,默认情况下,该构件会添加到新的 Java 项目中。更高级别的 CDK 支持仍在开发中的服务模块位于单独的“实验”软件包中,并以其服务名称的简短版本(不带 AWS 或 Amazon 前缀)命名。搜索 Maven Central 存储库
注意
CDK API Reference 的 Java 版本也显示了包名称。
某些服务的 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 中管理依赖项
在 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 IDE 都集成了 Maven 支持和可视化 pom.xml 编辑器,您可能会发现这很便于管理依赖项。
Maven 不支持依赖项锁定。尽管可以在 pom.xml 中指定版本范围,但我们建议您始终使用确切版本,以保持构建的可重复性。
Maven 会自动安装传递依赖项,但每个包只能安装一个副本。已选择 POM 树中指定的最高版本;应用程序对安装哪个版本的软件包始终拥有最终决定权。
每当您构建(mvn compile)或打包(mvn package)项目时,Maven 都会自动安装或更新您的依赖项。每次运行 CDK Toolkit 时,其都会自动执行此操作,因此通常无需手动调用 Maven。
Java 中的 AWS CDK 习语
Props
所有 AWS 构造库类都使用三个参数进行实例化:在其中定义构造的 scope(构造树中的父级)、id 和 props(构造用于配置其创建的资源的键/值对捆绑包)。其他类和方法也使用“属性捆绑包”模式作为参数。
在 Java 中,props 是使用生成器模式Bucket 构造(表示 Amazon S3 存储桶)将 BucketProps 的实例作为其 props。
BucketProps 类(与每个 AWS 构造库 props 类一样)有一个名为 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 类的移动部件。您可能更愿意只让您的构造接受一个或多个额外参数。如果参数是可选的,则应提供额外的构造函数。
通用结构
在某些 API 中,AWS CDK 使用 JavaScript 数组或非类型化对象作为方法的输入。(例如,请参阅 AWS CodeBuild 的 BuildSpec.fromObject() 方法。) 在 Java 中,这些对象表示为 java.util.Map<String, Object>。在值都为字符串的情况下,则可以使用 Map<String, String>。
与其他一些语言不同,Java 不提供为此类容器编写字面量的方法。在 Java 9 及更高版本中,您可以使用 java.util.Map.of()
java.util.Map.of( "base-directory", "dist", "files", "LambdaStack.template.json" )
要创建包含十个以上条目的映射,请使用 java.util.Map.ofEntries()
如果您使用的是 Java 8,则可以提供与这些方法类似的自己的方法。
JavaScript 数组在 Java 中表示为 List<Object> 或 List<String>。java.util.Arrays.asList 方法对于定义短 List 来说很方便。
List<String> cmds = Arrays.asList("cd lambda", "npm install", "npm install typescript")
缺失值
在 Java 中,AWS CDK 对象中的缺失值(例如 props)用 null 表示。您必须明确测试任何可能为 null 的值,以确保其包含一个值,然后才能用其进行操作。Java 不像其他一些语言有“语法糖”来帮助处理 null 值。您可能会发现 Apache ObjectUtil 的 defaultIfNullfirstNonNull
构建和运行 CDK 应用程序
在运行您的应用程序之前,AWS CDK 会自动对其进行编译。但是,手动构建应用程序以检查错误并运行测试可能会很有用。您可以在 IDE 中执行此操作(例如,在 Eclipse 中按 Control-B),也可以在项目的根目录中在命令提示符下发出 mvn compile 命令来执行此操作。
在命令提示符下运行 mvn test 命令来运行您编写的所有测试。