练习 - 使用 Maven 设置 Java 应用

已完成

在本单元中,你将通过使用所选的 IDE 来编辑代码,以创建基本控制台应用。 你可以选择使用自己所选的终端来运行代码。

创建 Azure Cosmos DB 资源

为帮助完成本实验室,Microsoft Learn 提供了可在其中创建帐户和资源的免费 Azure 沙盒。 你将在此订阅中设置一个 Azure Cosmos DB 帐户,然后创建数据库和容器。

  1. 使用激活沙盒时所用的同一帐户登录到 Azure 门户
  2. 在 Azure 门户中,使用你选择的名称创建一个 Azure Cosmos DB 帐户。 当可以为帐户选择资源组时,请查找资源组 [沙盒资源组] 并将其选中。
  3. 在 Azure Cosmos DB 帐户中创建一个名为“用户”的数据库。
  4. 在 Users 数据库中,创建一个名为 WebCustomers 的容器,其分区键为 /userId。 为 WebCustomers 预配 400 RU/秒。

创建工作目录

  1. 我们为 Java 应用程序提供了模板。 将模板存储库克隆到系统上。

    git clone https://github.com/MicrosoftDocs/mslearn-cosmos-java-sql.git
    
  2. 打开 Windows 文件资源管理器并转到克隆的存储库。 进入 java_lab 子目录。

    重要

    本模块的所有工作都将位于 java_lab 子目录下。

  3. 该模板包含 Maven pom.xml 文件,它已为项目提取了所需的依赖项。 打开此文件并进行检查,查找以下依赖项:

    <dependency>
        <groupId>com.azure</groupId>
        <artifactId>azure-cosmos</artifactId>
        <version>LATEST</version>
    </dependency>
    

    此依赖项会拉取 Azure Cosmos DB Java SDK 最新版本。 可以关闭此文件。

  4. 接下来,将构建并运行 Hello World。 使用 IDE 或终端打开此项目。 根据你的 IDE,可选择在 Java 子目录中以项目形式打开 pom.xml 文件。

    打开项目后,转到 src/main/java/com/azure/cosmos/examples/mslearnbasicapp,然后打开 CosmosApp.java,这是我们将要开发的 Java 应用程序的模板。 结果应如下所示:

    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    
    public final class CosmosApp {
    
        /** For application to log INFO and ERROR. */
        private static Logger logger = LoggerFactory.getLogger(CosmosApp.class.getSimpleName());
    
        private CosmosApp() {
            // not called
        }
    
        /**
        * Main.
        * @param args Command line arguments
        */
        public static void main(final String[] args) {
            logger.info("Hello World.");
        }
    }
    

    就像现在一样,应用程序代码实现简单的“Hello World”。

  5. 如果 IDE 提供了生成并运行 Maven 应用程序的工具:使用 IDE 生成并运行应用程序,并确认应用程序日志 Hello World 记录到终端。

  6. 如果要使用终端生成并运行 Maven 应用程序:使用以下命令来生成 Maven 项目:

    mvn clean package
    

    然后运行:

    mvn exec:java -Dexec.mainClass="com.azure.cosmos.examples.mslearnbasicapp.CosmosApp"  
    

    确认应用程序将以下输出记录到终端:

    INFO: Hello World.
    

将应用连接到 Azure Cosmos DB

  1. CosmosApp 类中,创建以下用于 Azure Cosmos DB 连接详细信息的静态类变量:

    /** Azure Cosmos DB endpoint URI. */
    private static String endpointUri = "<your-cosmosdb-hostname>";
    
    /** Azure Cosmos DB primary key. */
    private static String primaryKey = "<your-cosmosdb-master-key>";
    
  2. 回到 Azure 门户,转到“密钥”窗格,并将 Azure Cosmos DB 终结点 URI 和主密钥复制到上述变量定义中。

    例如,如果 URI 是 https://cosmosacct.documents.azure.com:443/,则新变量分配将如下所示:private static String endpointUri = "https://cosmosacct.documents.azure.com:443/";。 如果主密钥是 elzirrKCnXlacvh1CRAnQdYVbVLspmYHQyYrhx0PltHi8wn5lHVHFnd1Xm3ad5cn4TUcH4U0MSeHsVykkFPHpQ==,则新变量分配将如下所示:private static String primaryKey = "elzirrKCnXlacvh1CRAnQdYVbVLspmYHQyYrhx0PltHi8wn5lHVHFnd1Xm3ad5cn4TUcH4U0MSeHsVykkFPHpQ==";

创建 CosmosAsyncClient 实例

现在可以创建 CosmosAsyncClient 的实例了,它是 Azure Cosmos DB 服务的客户端表示形式。 此客户端用于对服务配置和执行请求。

  1. 在 CosmosApp.java 中,将以下静态变量声明添加到 CosmosApp 类中:

    /** Azure Cosmos DB client instance. */
    private static CosmosAsyncClient client;
    
    /** Azure Cosmos DB database instance. */
    private static CosmosAsyncDatabase database;
    
    /** Azure Cosmos DB container instance. */
    private static CosmosAsyncContainer container;
    

    最可能的情况是,clientdatabasecontainer 类尚未导入到 Java 文件中。 所以现在是处理这个问题的好时机。 某些 IDE 可以根据键入的代码自动导入依赖项,这在此处非常有用。 通常情况下,当我们提供要粘贴到的代码块时,你可能需要添加一些 import 语句,才能使其正常运行。

  2. 在类中创建不带参数的 private void 方法 basicOperations

  3. 添加以下代码,在 basicOperations 方法中创建 CosmosAsyncClient 实例,并包含用于检查“用户”数据库是否存在的代码。

     client = new CosmosClientBuilder()
         .endpoint(endpointUri)
         .key(primaryKey)
         .consistencyLevel(ConsistencyLevel.EVENTUAL)
         .directMode()
         .contentResponseOnWriteEnabled(true)
         .buildAsyncClient();
    
     database = client.getDatabase("Users");
     container = database.getContainer("WebCustomers");            
    
     logger.info("Database and container validation complete");
    
     client.close();
    
  4. 此时,basicOperations 方法包含要与 Azure Cosmos DB 交互的代码。 但是,main 中不会调用此方法,因此,我们的应用程序仍可用于打印“Hello World”。作为一种验证,请在 IDE 中构建并运行 CosmosApp.java 或使用以下命令在终端中运行程序:

    mvn clean package
    mvn exec:java -Dexec.mainClass="com.azure.cosmos.examples.mslearnbasicapp.CosmosApp"  
    

    确认应用仍将以下输出记录到终端:

    INFO: Hello World.
    
  5. 将以下代码复制粘贴到 main 方法中,覆盖当前的 logger.info("Hello World."); 行。

    try {
        CosmosApp p = new CosmosApp();
        p.basicOperations();
    } catch (CosmosException e) {
        logger.error("Failed while executing app.", e);
    } finally {
        logger.info("End of demo, press any key to exit.");
    }
    

    这将触发应用程序中的 Azure Cosmos DB 代码。

  6. 在 IDE 中生成并运行 CosmosApp.java,或使用以下内容在终端中运行程序:

    mvn clean package
    mvn exec:java -Dexec.mainClass="com.azure.cosmos.examples.mslearnbasicapp.CosmosApp"  
    

    你可能会在终端中看到大量日志消息,其中一些是由 SDK 本身生成的。 通读并确认应用已将以下输出记录到终端:

    INFO: Database and container validation complete
    

在本单元中,我们将建立 Azure Cosmos DB Java 应用程序的基础。 你要设置 Maven 应用程序,创建一个基本的“Hello World”项目,并对塔进行扩展,将项目连接到 Azure Cosmos DB 终结点。

  1. 我们为 Java 应用程序提供了模板。 请将模板存储库克隆到系统上

    git clone https://github.com/MicrosoftDocs/mslearn-cosmos-java-sql.git
    
  2. 打开 Windows 资源管理器,并导航到克隆存储库。 进入 spring_lab 子目录。

    重要

    本模块的所有工作都将位于 spring_lab 子目录下。

  3. 该模板包含 Maven pom.xml,它已为项目提取了所需的依赖项。 打开此文件并进行检查,查找以下依赖项:

    <dependency>
      <groupId>com.azure</groupId>
      <artifactId>azure-spring-data-cosmos</artifactId>
      <version>LATEST</version>
    </dependency>
    

    此依赖项会拉取 Spring Data Azure Cosmos DB 最新版本。 可以关闭此文件。

将应用连接到 Azure Cosmos DB

  1. 使用 IDE 或终端打开此项目。 根据你的 IDE,可选择在 spring 子目录中以项目形式打开 pom.xml 文件。 打开项目后,使用文件资源管理器工具导航到 src/main/resources/。 应会看到名为 application.properties.rename 的文件。 Spring Data 通过硬编码配置参数强调配置文件;若要为 Spring Data 项目创建配置文件,请将 application.properties.rename 复制到 application.properties,并打开新的 application.properties 文件。 在网站底部应会看到

    cosmos.uri=${ACCOUNT_HOST}
    cosmos.key=${ACCOUNT_KEY}
    cosmos.secondaryKey=${SECONDARY_ACCOUNT_KEY}
    
    dynamic.collection.name=spel-property-collection
    # Populate query metrics
    cosmos.queryMetricsEnabled=true
    

    你将使用所选的方法来填充 ${ACCOUNT_HOST}${ACCOUNT_KEY} - 将值复制并粘贴到 application.properties 中,或在 IDE 中定义这些环境变量。 在下一步中,你将找到这些变量应具有的值。

  2. 回到 Azure 门户,转到“密钥”窗格,并复制 Azure Cosmos DB 终结点 URI 和主密钥。 如前一步骤中所述,使用所选的方法将 Azure Cosmos DB 终结点 URI 和主密钥分配给上述变量。

    例如,如果 URI 是 https://cosmosacct.documents.azure.com:443/,并且你选择将终结点和主密钥粘贴到 application.properties 中,则 application.properties 中的行将随后如下所示:cosmos.uri=https://cosmosacct.documents.azure.com:443/。 如果主密钥是 elzirrKCnXlacvh1CRAnQdYVbVLspmYHQyYrhx0PltHi8wn5lHVHFnd1Xm3ad5cn4TUcH4U0MSeHsVykkFPHpQ==,则按照相同的过程操作,新变量分配将如下所示:cosmos.key=elzirrKCnXlacvh1CRAnQdYVbVLspmYHQyYrhx0PltHi8wn5lHVHFnd1Xm3ad5cn4TUcH4U0MSeHsVykkFPHpQ==

配置 Azure Cosmos DB 客户端

Spring Data Azure Cosmos DB 在启动时自动实例化 Azure Cosmos DB 客户端。 Azure Cosmos DB 客户端是用于对服务执行请求的 Azure Cosmos DB 服务的客户端表示形式。 你的代码可以使用一组生成器方法以及从 application.properties 中拉取的属性,在实例化之前配置 Azure Cosmos DB 客户端。

  1. 打开 CosmosProperties.java。 我们提供的此文件是已完成的表单格式,因此只需检查其内容。

    @ConfigurationProperties(prefix = "cosmos")
    public class CosmosProperties {
    
        private String uri;
    
        private String key;
    
        private String secondaryKey;
    
        private boolean queryMetricsEnabled;
    
        public String getUri() {
            return uri;
        }
    
        public void setUri(String uri) {
            this.uri = uri;
        }
    
        public String getKey() {
            return key;
        }
    
        public void setKey(String key) {
            this.key = key;
        }
    
        public String getSecondaryKey() {
            return secondaryKey;
        }
    
        public void setSecondaryKey(String secondaryKey) {
            this.secondaryKey = secondaryKey;
        }
    
        public boolean isQueryMetricsEnabled() {
            return queryMetricsEnabled;
        }
    
        public void setQueryMetricsEnabled(boolean enableQueryMetrics) {
            this.queryMetricsEnabled = enableQueryMetrics;
        }
    }
    

    观察类成员 urikeysecondaryKeyqueryMetricsEnabled。 回头查看 application.properties,会发现 CosmosProperties 成员名称与 application.properties 属性名称密切对应。 CosmosProperties 类为应用程序的其余部分提供了 getter 和 setter,以便从 application.properties 访问配置设置。 请注意,此处没有用于从 application.properties 拉取配置的代码 - Spring Data 了解此文件的结构,并在分析配置文件之后自动设置成员变量。

    当我们配置 Azure Cosmos DB 客户端时,将利用这一设置。

  2. 在 CosmosSampleConfiguration.java 中,检查 CosmosSampleConfiguration 类并查找空的 cosmosClientBuilder 方法:

    @Bean
    public CosmosClientBuilder cosmosClientBuilder() {
        return null;
    }
    

    在启动时,Spring Data 将自动调用此方法,获取此方法返回的 CosmosClientBuilder,并调用其 build() 方法(在后台)- 这时将基于 CosmosClientBuilder 中包含的配置设置创建 CosmosAsyncClient 实例。 你可以利用此方法配置使用生成器方法的 CosmosClientBuilder

  3. 请注意,我们使用构造函数注入(而不是使用 @Autowired) 的字段注入)来实例化 properties 变量,并使用配置文件中的解析值填充其成员变量。 这样可以确保在创建此类的实例时存在所有必需的依赖项,并有助于将来编写测试代码。

    //use constructor injection for spring dependencies 
    public CosmosSampleConfiguration(CosmosProperties properties){
        this.properties = properties;
    }
    

    我们可以使用 properties 获取 Azure Cosmos DB 帐户的 URI 和密钥,并实现 cosmosClientBuilder,如下所示:

    @Bean
    public CosmosClientBuilder cosmosClientBuilder() {
        DirectConnectionConfig directConnectionConfig = DirectConnectionConfig.getDefaultConfig();
        return new CosmosClientBuilder()
            .endpoint(properties.getUri())
            .key(properties.getKey())
            .directMode(directConnectionConfig);
    }
    

    此实现

    1. properties 中拉取 URI 和密钥
    2. 将它们插入 endpointkey 生成器方法
    3. 此外,还配置与 Azure Cosmos DB 服务的网络连接。 (在直接模式下,客户端应用程序直接与后端 Azure Cosmos DB 分区进行通信。)
  4. 返回 CosmosSampleConfiguration.java 并查找 getDatabaseName 方法:

    @Override
    protected String getDatabaseName() { return ""; }
    

    将默认返回值更改为 "Users",即数据库的名称。 这样一来,当 Spring Data 在启动时自动连接到 Azure Cosmos DB 时,它将连接到 *Users 数据库。

  5. 导航到 WebCustomer.java。 你会注意到 WebCustomer 类前面有一个 @Container 注释:

    @Container(containerName = "", ru = "")
    

    @Container 采用两个参数:

    • containerName:Azure Cosmos DB 容器的名称(WebCustomers)
    • ru:容器的预配吞吐量。 对于 Microsoft Learn 练习,400 RU/秒是一个很好的默认值。

    自定义用例的 @Container,如下所示:

    @Data
    @NoArgsConstructor
    @AllArgsConstructor
    @Container(containerName = "WebCustomers", ru = "400")
    public class WebCustomer {
    
  6. 此时,你的 Spring Data 项目设置为与 Azure Cosmos DB 交互。 接下来,将构建并运行 Hello World。 转到 src/main/java/com/azure/cosmos/examples/springexamples,然后打开 CosmosSample.java,这是我们将要开发的 Spring Data 应用程序的模板。 结果应如下所示:

    // Copyright (c) Microsoft Corporation. All rights reserved.
    // Licensed under the MIT License.
    package com.azure.cosmos.examples.springexamples;
    
    import com.azure.cosmos.CosmosException;
    import com.azure.cosmos.examples.springexamples.common.CouponsUsed;
    import com.azure.cosmos.examples.springexamples.common.OrderHistory;
    import com.azure.cosmos.examples.springexamples.common.ShippingPreference;
    import com.azure.cosmos.models.CosmosItemResponse;
    import com.azure.cosmos.models.PartitionKey;
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    import org.springframework.boot.CommandLineRunner;
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    import reactor.core.publisher.Flux;
    import reactor.core.publisher.Mono;
    
    import java.util.ArrayList;
    import java.util.Arrays;
    import java.util.List;
    
    @SpringBootApplication
    public class CosmosSample implements CommandLineRunner {
    
        private final Logger logger = LoggerFactory.getLogger(CosmosSample.class);
    
        private ReactiveWebCustomerRepository reactiveWebCustomerRepository;
    
        //constructor dependency injection
        public CosmosSample(ReactiveWebCustomerRepository reactiveWebCustomerRepository){
            this.reactiveWebCustomerRepository = reactiveWebCustomerRepository;
        }
    
        public void run(String... var1) {
            logger.info("Hello world.");
        }
    }
    

    就像现在一样,应用程序代码实现简单的“Hello World”。

  7. 如果 IDE 提供了生成并运行 Maven 应用程序的工具:使用 IDE 生成并运行应用程序,并确认应用程序日志 Hello World 记录到终端。

  8. 如果要使用终端生成并运行 Maven 应用程序:使用以下命令来生成 Maven 项目:

    mvn clean package
    

    然后运行:

    mvn spring-boot:run
    

    确认在所有其他输出中,应用程序将以下输出记录到终端:

    INFO: Hello World.
    

在本单元中,我们将建立 Azure Cosmos DB Java 应用程序的基础。 你自定义了 Maven 应用程序,并扩展了一个基本的“Hello World”项目以连接到 Azure Cosmos DB 终结点。