

這是 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 (Oracle 的 或 OpenJDK 分佈，例如 Amazon Corretto) 和 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、NetBeans 和其他 IDEs 可以匯入 Maven 專案，並可用於在 Java 中開發 AWS CDK 應用程式。

可以使用 Java 以外的 JVM 託管語言 （例如 Kotlin、Groovy、Clojure 或 Scala) 撰寫 AWS CDK 應用程式，但體驗可能不特別特殊，我們無法為這些語言提供任何支援。

## Java 入門
<a name="java-prerequisites"></a>

若要使用 AWS CDK，您必須擁有 AWS 帳戶和登入資料，並已安裝 Node.js 和 AWS CDK Toolkit。請參閱 [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 Toolkit 產生的應用程式骨架是 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 安裝組 中的 AWS 建構程式庫套件`software.amazon.awscdk`。大多數建構在成品 中`aws-cdk-lib`，預設會新增至新的 Java 專案。目前仍在開發更高層級 CDK 支援之服務的模組，採用個別的「實驗性」套件，以其服務名稱的簡短版本 （無 AWS 或 Amazon 字首） 命名。[搜尋 Maven 中央儲存庫](https://search.maven.org/search?q=software.amazon.awscdk)，尋找所有 AWS CDK 和 AWS 建構模組程式庫的名稱。

**注意**  
[CDK API 參考的 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 Construct Library 中各種服務的模組位於 下`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 相依性的功能。不過，我們建議您`pom.xml`直接編輯 ，除非您確定 IDE 的功能符合您手動執行的操作。

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

在 Java 中，相依性是在 中指定，`pom.xml`並使用 Maven 安裝。`<dependencies>` 容器包含每個套件的 `<dependency>`元素。以下是`pom.xml`典型 CDK Java 應用程式的 區段。

```
<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 樹狀目錄中指定的最高版本；應用程式一律在安裝的套件版本中具有最後一個字。

Maven 會在您建置 (`mvn compile`) 或封裝 (`mvn package`) 專案時自動安裝或更新相依性。CDK Toolkit 會在每次執行時自動執行此操作，因此通常不需要手動叫用 Maven。

## AWS Java 中的 CDK 慣用語
<a name="java-cdk-idioms"></a>

### 屬性
<a name="java-props"></a>

所有 AWS 建構程式庫類別都會使用三個引數來執行個體化：定義建構*的範圍* （其在建構樹狀結構中的父系）、*id* 和 *props*，即建構函數用來設定其建立之資源的金鑰/值對套件。其他類別和方法也會針對引數使用「屬性組合」模式。

在 Java 中，props 是使用 [Builder 模式](https://en.wikipedia.org/wiki/Builder_pattern)來表示。每個建構類型都有對應的道具類型；例如，建構 `Bucket` （代表 Amazon S3 儲存貯體） 採用 做為其道具 執行個體`BucketProps`。

`BucketProps` 類別 （如同每個 AWS Construct Library 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());
```

建構和其他使用類似道具物件作為其最終引數的類別，提供捷徑。類別具有`Builder`自己的 ，可在一個步驟中執行個體化它及其道具物件。如此一來，您不需要明確執行個體化 （例如） `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 中，prop 等 AWS CDK 物件中的遺失值會以 表示`null`。您必須明確測試任何值，`null`以確保它包含值，然後再執行任何操作。Java 沒有協助處理 Null 值的「語法糖」，就像某些其他語言一樣。在某些情況下，您可能會發現 Apache ObjectUtil 的 [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-)和 很有[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`中執行 ，以執行您撰寫的任何測試。