本指南将引导您逐步完成使用Spring Integration通道适配器Google Cloud Pub / Sub作为底层消息交换机制在程序的不同部分之间或不同程序之间交换消息的过程。

你会建立什么

一个Spring Boot Web应用程序,它向自身发送消息并处理这些消息。

你需要什么

如何完成本指南

像大多数Spring入门指南一样,您可以从头开始并完成每个步骤,也可以绕过您已经熟悉的基本设置步骤。无论哪种方式,您最终都可以使用代码。

从头开始,请继续使用Gradle构建

跳过基础知识,请执行以下操作:

完成后,您可以根据中的代码检查结果gs-messaging-gcp-pubsub/complete

用Gradle构建

用Gradle构建

首先,您设置一个基本的构建脚本。在使用Spring构建应用程序时,可以使用任何喜欢的构建系统,但是此处包含使用GradleMaven所需的代码。如果您都不熟悉,请参阅使用Gradle构建Java项目使用Maven构建Java项目

创建目录结构

在您选择的项目目录中,创建以下子目录结构;例如,mkdir -p src/main/java/hello在* nix系统上:

└──src
    main──主要
        └──java
            └──你好

创建一个Gradle构建文件

build.gradle

buildscript {
    repositories {
        mavenCentral()
    }
    dependencies {
        classpath("org.springframework.boot:spring-boot-gradle-plugin:2.3.4.RELEASE")
    }
}

apply plugin: 'java'
apply plugin: 'eclipse'
apply plugin: 'idea'
apply plugin: 'org.springframework.boot'
apply plugin: 'io.spring.dependency-management'

bootJar {
    baseName = 'gs-spring-cloud-gcp'
    version =  '0.1.0'
}

repositories {
    mavenCentral()
}

sourceCompatibility = 1.8
targetCompatibility = 1.8

dependencies {
    compile("org.springframework.boot:spring-boot-starter-web")
    testCompile("org.springframework.boot:spring-boot-starter-test")
}

Spring的Gradle启动插件提供了许多便捷的功能:

  • 它收集类路径上的所有jar,并构建一个可运行的单个“über-jar”,这使执行和传输服务更加方便。

  • 它搜索public static void main()要标记为可运行类的方法。

  • 它提供了一个内置的依赖项解析器,用于设置版本号以匹配Spring Boot依赖项。您可以覆盖所需的任何版本,但是它将默认为Boot选择的一组版本。

用Maven编译

用Maven编译

首先,您设置一个基本的构建脚本。使用Spring构建应用程序时,可以使用任何喜欢的构建系统,但是此处包含了使用Maven所需的代码。如果您不熟悉Maven,请参阅使用Maven构建Java项目

创建目录结构

在您选择的项目目录中,创建以下子目录结构;例如,mkdir -p src/main/java/hello在* nix系统上:

└──src
    main──主要
        └──java
            └──你好

pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<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">
    <modelVersion>4.0.0</modelVersion>

    <groupId>org.springframework</groupId>
    <artifactId>gs-spring-cloud-gcp</artifactId>
    <version>0.1.0</version>

    <properties>
        <java.version>1.8</java.version>
        <spring-boot-release.version>2.3.4.RELEASE</spring-boot-release.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
    </dependencies>

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-dependencies</artifactId>
                <version>${spring-boot-release.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>

Spring启动Maven插件提供了许多便捷的功能:

  • 它收集类路径上的所有jar,并构建一个可运行的单个“über-jar”,这使执行和传输服务更加方便。

  • 它搜索public static void main()要标记为可运行类的方法。

  • 它提供了一个内置的依赖项解析器,用于设置版本号以匹配Spring Boot依赖项。您可以覆盖所需的任何版本,但是它将默认为Boot选择的一组版本。

使用您的IDE进行构建

使用您的IDE进行构建

添加所需的依赖项

pom.xml如果您使用的是Maven ,请在文件中添加以下内容:

<dependencies>
    ...
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-gcp-starter-pubsub</artifactId>
    </dependency>

    <dependency>
        <groupId>org.springframework.integration</groupId>
        <artifactId>spring-integration-core</artifactId>
    </dependency>
    ...
</dependencies>

或者,如果您使用的是Gradle:

dependencies {
    ...
    compile("org.springframework.cloud:spring-cloud-gcp-starter-pubsub:1.2.5.RELEASE")
    compile("org.springframework.integration:spring-integration-core")
    ...
}

如果您使用的是Maven,还强烈建议您使用Spring Cloud GCP物料清单来控制依赖项的版本:

<properties>
    ...
    <spring-cloud-gcp.version>1.2.5.RELEASE</spring-cloud-gcp.version>
    ...
</properties>

<dependencyManagement>
    <dependencies>
       ...
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-gcp-dependencies</artifactId>
            <version>${spring-cloud-gcp.version}</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
        ...
    </dependencies>
</dependencyManagement>

设置Google Cloud Pub / Sub环境

您需要一个主题和一个订阅,才能从Google Cloud Pub / Sub发送和接收消息。您可以在Google Cloud Console中创建它们,也可以使用PubSubAdmin该类通过编程创建它们。

在本练习中,创建一个名为“ testTopic”的主题,并为该主题创建一个名为“ testSubscription”的订阅。

创建应用程序文件

您将需要一个类来包括通道适配器和消息传递配置。与Spring Boot应用程序一样,使用@SpringBootApplication标头创建PubSubApplication类。

src/main/java/hello/PubSubApplication.java

@SpringBootApplication
public class PubSubApplication {

  public static void main(String[] args) throws IOException {
    SpringApplication.run(PubSubApplication.class, args);
  }

}

此外,由于您正在构建Web应用程序,因此请创建WebAppController类以在控制器和配置逻辑之间进行分隔。

src/main/java/hello/WebAppController.java

@RestController
public class WebAppController {
}

我们仍然缺少HTML和属性的两个文件。

src/main/resources/static/index.html

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Spring Integration GCP sample</title>
</head>
<body>
<div name="formDiv">
  <form action="/publishMessage" method="post">
    Publish message: <input type="text" name="message" /> <input type="submit" value="Publish!"/>
  </form>
</div>
</body>
</html>

src/main/resources/application.properties

#spring.cloud.gcp.project-id=[YOUR_GCP_PROJECT_ID_HERE]
#spring.cloud.gcp.credentials.location=file:[LOCAL_FS_CREDENTIALS_PATH]

Spring Cloud GCP Core Boot启动器可以自动配置这两个属性并使它们成为可选属性。属性文件中的属性始终优先于Spring Boot配置。Spring Cloud GCP Core Boot启动器与Spring Cloud GCP Pub / Sub Boot启动器捆绑在一起。

GOOGLE_CLOUD_PROJECT除了其他几个来源外,还可以从环境变量中自动配置GCP项目ID 。OAuth2凭据是通过GOOGLE_APPLICATION_CREDENTIALS环境变量自动配置的。如果安装了Google Cloud SDK,则可以通过gcloud auth application-default login在应用的同一进程或父进程中运行该命令来轻松配置此环境变量。

创建入站通道适配器

入站通道适配器侦听来自Google Cloud Pub / Sub订阅的消息,并将其发送到应用程序中的Spring通道。

实例化入站通道适配器需要PubSubTemplate实例和现有订阅的名称。PubSubTemplate是Spring订阅Google Cloud Pub / Sub主题的抽象。Spring Cloud GCP发布/订阅启动启动器提供了一个自动配置的PubSubTemplate实例,您可以将其简单地注入为方法参数。

src/main/java/hello/PubSubApplication.java

  @Bean
  public PubSubInboundChannelAdapter messageChannelAdapter(
    @Qualifier("pubsubInputChannel") MessageChannel inputChannel,
    PubSubTemplate pubSubTemplate) {
  PubSubInboundChannelAdapter adapter =
    new PubSubInboundChannelAdapter(pubSubTemplate, "testSubscription");
  adapter.setOutputChannel(inputChannel);
  adapter.setAckMode(AckMode.MANUAL);

  return adapter;
  }

默认情况下,消息确认模式在适配器中设置为自动。如示例所示,此行为可能会被覆盖。

实例化通道适配器后,必须配置适配器将接收到的消息发送到的输出通道。

src/main/java/hello/PubSubApplication.java

  @Bean
  public MessageChannel pubsubInputChannel() {
  return new DirectChannel();
  }

连接到入站通道的是服务激活器,用于处理传入消息。

src/main/java/hello/PubSubApplication.java

  @Bean
  @ServiceActivator(inputChannel = "pubsubInputChannel")
  public MessageHandler messageReceiver() {
  return message -> {
    LOGGER.info("Message arrived! Payload: " + new String((byte[]) message.getPayload()));
    BasicAcknowledgeablePubsubMessage originalMessage =
    message.getHeaders().get(GcpPubSubHeaders.ORIGINAL_MESSAGE, BasicAcknowledgeablePubsubMessage.class);
    originalMessage.ack();
  };
  }

ServiceActivator输入信道的名称(例如,"pubsubInputChannel")必须与输入信道的方法的名称相匹配。每当有新消息到达该频道时,返回的都会对其进行处理MessageHandler

在此示例中,仅通过记录其正文并确认该消息即可对其进行处理。在手动确认中,将使用BasicAcknowledgeablePubsubMessage对象确认消息,该对象附加在Message标题上,并且可以使用GcpPubSubHeaders.ORIGINAL_MESSAGE密钥将其提取。

创建一个出站通道适配器

出站通道适配器侦听来自Spring通道的新消息,并将其发布到Google Cloud Pub / Sub主题。

实例化出站通道适配器需要一个PubSubTemplate和一个现有主题的名称。PubSubTemplate是Spring的抽象概念,用于将消息发布到Google Cloud Pub / Sub主题。Spring Cloud GCP发布/订阅启动启动器提供了一个自动配置的PubSubTemplate实例。

src/main/java/hello/PubSubApplication.java

  @Bean
  @ServiceActivator(inputChannel = "pubsubOutputChannel")
  public MessageHandler messageSender(PubSubTemplate pubsubTemplate) {
  return new PubSubMessageHandler(pubsubTemplate, "testTopic");
  }

您可以使用MessageGateway将消息写入频道,然后将其发布到Google Cloud Pub / Sub。

src/main/java/hello/PubSubApplication.java

  @MessagingGateway(defaultRequestChannel = "pubsubOutputChannel")
  public interface PubsubOutboundGateway {

  void sendToPubsub(String text);
  }

通过此代码,Spring自动生成一个对象,然后可以将该对象自动连接到应用程序的私有字段中。

src/main/java/hello/WebAppController.java

  @Autowired
  private PubsubOutboundGateway messagingGateway;

添加控制器逻辑

向控制器添加逻辑,使您可以写入Spring通道:

src/main/java/hello/WebAppController.java

package hello;

import hello.PubSubApplication.PubsubOutboundGateway;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.servlet.view.RedirectView;

@RestController
public class WebAppController {

  // tag::autowireGateway[]
  @Autowired
  private PubsubOutboundGateway messagingGateway;
  // end::autowireGateway[]

  @PostMapping("/publishMessage")
  public RedirectView publishMessage(@RequestParam("message") String message) {
  messagingGateway.sendToPubsub(message);
  return new RedirectView("/");
  }
}

验证

您的应用程序必须通过GOOGLE_APPLICATION_CREDENTIALS环境变量或spring.cloud.gcp.credentials.location属性进行身份验证。

如果您安装了Google Cloud SDK,则可以使用该gcloud auth application-default login命令以您的用户帐户登录。

或者,您可以从Google Cloud Console下载服务帐户凭据文件,然后spring.cloud.gcp.credentials.locationapplication.properties文件中的属性指向该文件。

作为Spring Resourcespring.cloud.gcp.credentials.location也可以从文件系统之外的其他地方(例如URL,类路径等)获得这些资源

使应用程序可执行

尽管可以将该服务打包为传统的WAR文件以部署到外部应用程序服务器,但是下面演示的更简单的方法创建了一个独立的应用程序。您将所有内容打包在一个由Javamain()方法驱动的单个可执行JAR文件中。另外,您使用Spring的支持将Tomcat servlet容器作为HTTP运行时嵌入,而不是部署到外部实例。

@SpringBootApplication 是一个方便注释,它添加了以下所有内容:

  • @Configuration:将类标记为应用程序上下文的Bean定义的源。

  • @EnableAutoConfiguration:告诉Spring Boot根据类路径设置,其他bean和各种属性设置开始添加bean。例如,如果spring-webmvc在类路径上,则此注释将应用程序标记为Web应用程序并激活关键行为,例如设置DispatcherServlet

  • @ComponentScan:告诉Spring在包中寻找其他组件,配置和服务hello,让它找到控制器。

main()方法使用Spring Boot的SpringApplication.run()方法来启动应用程序。您是否注意到没有一行XML?也没有web.xml文件。该Web应用程序是100%纯Java,因此您无需处理任何管道或基础结构。

建立可执行的JAR

您可以使用Gradle或Maven从命令行运行该应用程序。您还可以构建一个包含所有必需的依赖项,类和资源的可执行JAR文件,然后运行该文件。生成可执行jar使得在整个开发生命周期中,跨不同环境等等的情况下,都可以轻松地将服务作为应用程序进行发布,版本控制和部署。

如果您使用Gradle,则可以使用来运行该应用程序./gradlew bootRun。或者,您可以使用来构建JAR文件./gradlew build,然后运行JAR文件,如下所示:

java -jar build / libs / gs-messaging-gcp-pubsub-0.1.0.jar

如果您使用Maven,则可以使用来运行该应用程序./mvnw spring-boot:run。或者,您可以使用来构建JAR文件,./mvnw clean package然后运行JAR文件,如下所示:

java -jar target / gs-messaging-gcp-pubsub-0.1.0.jar
此处描述的步骤将创建可运行的JAR。您还可以构建经典的WAR文件

显示日志记录输出。该服务应在几秒钟内启动并运行。

测试应用程序

现在该应用程序正在运行,您可以对其进行测试。打开http:// localhost:8080,在输入文本框中键入一条消息,然后按“发布!” 按钮并确认消息已正确记录在您的过程终端窗口中。

概括

恭喜你!您刚刚开发了一个Spring应用程序,该应用程序使用Spring Integration GCP发布/订阅通道适配器来交换消息!

是否要编写新指南或为现有指南做出贡献?查看我们的贡献准则

所有指南均以代码的ASLv2许可证和写作的Attribution,NoDerivatives创用CC许可证发布。