Introduction to Spring Integration – Spring集成简介

最后修改: 2016年 12月 13日

中文/混合/英文(键盘快捷键:t)

1. Introduction

1.介绍

This article will introduce the core concepts of Spring Integration primarily through small, practical examples.

本文将主要通过小型的实际例子来介绍Spring Integration的核心概念

Spring Integration provides a lot of powerful components that can greatly enhance the interconnectivity of systems and processes within an enterprise architecture.

Spring Integration提供了很多强大的组件,可以大大增强企业架构中系统和流程的互连性。

It embodies the some of the finest and most popular design patterns, helping developers avoid rolling their own.

它体现了一些最好的和最流行的设计模式,帮助开发者避免推出自己的设计。

We will take a look at the specific needs that this library fills in an enterprise application and why it is advisable over some of its alternatives. We will also look at some available tools for further simplifying the development of Spring Integration-based applications.

我们将看看这个库在企业应用中的具体需求,以及为什么它比一些替代品更值得推荐。我们还将研究一些可用的工具,以进一步简化基于Spring集成的应用的开发。

2. Setup

2.设置

<dependency>
    <groupId>org.springframework.integration</groupId>
    <artifactId>spring-integration-core</artifactId>
    <version>4.3.5.RELEASE</version>
</dependency>
<dependency>
    <groupId>org.springframework.integration</groupId>
    <artifactId>spring-integration-file</artifactId>
    <version>4.3.5.RELEASE</version>
</dependency>

You can download the latest versions of Spring Integration Core and the Spring Integration File Support from Maven Central.

您可以从Maven中心下载最新版本的Spring集成核心Spring集成文件支持

3. The Messaging Pattern

3.消息传递模式</b

One of the foundational patterns in this library is Messaging. The pattern is centered around messages – discrete payloads of data that move from an originating system or process to one or multiple systems or processes via predefined channels.

这个库中的一个基本模式是消息传递。该模式以消息为中心–离散的数据有效载荷,通过预定义的渠道从一个源系统或流程移动到一个或多个系统或流程。

Historically, the pattern arose as the most flexible way to integrate multiple disparate systems in a way that:

从历史上看,这种模式是作为以一种最灵活的方式来整合多个不同的系统而出现的。

  • Almost completely decouples the systems involved in the integration
  • Allows participant systems in the integration to be completely agnostic of each others underlying protocols, formatting, or other implementation details
  • Encourages the development and reuse of components involved in the integration

4. Messaging Integration in Action

4.行动中的信息整合

Let’s consider a basic example that copies a MPEG video file from a designated folder to another configured folder:

让我们考虑一个基本的例子,将一个MPEG视频文件从一个指定的文件夹复制到另一个配置的文件夹。

@Configuration
@EnableIntegration
public class BasicIntegrationConfig{
    public String INPUT_DIR = "the_source_dir";
    public String OUTPUT_DIR = "the_dest_dir";
    public String FILE_PATTERN = "*.mpeg";

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

    @Bean
    @InboundChannelAdapter(value = "fileChannel", poller = @Poller(fixedDelay = "1000"))
    public MessageSource<File> fileReadingMessageSource() {
        FileReadingMessageSource sourceReader= new FileReadingMessageSource();
        sourceReader.setDirectory(new File(INPUT_DIR));
        sourceReader.setFilter(new SimplePatternFileListFilter(FILE_PATTERN));
        return sourceReader;
    }

    @Bean
    @ServiceActivator(inputChannel= "fileChannel")
    public MessageHandler fileWritingMessageHandler() {
        FileWritingMessageHandler handler = new FileWritingMessageHandler(new File(OUTPUT_DIR));
        handler.setFileExistsMode(FileExistsMode.REPLACE);
        handler.setExpectReply(false);
        return handler;
    }
}

The code above configures a service activator, an integration channel, and an inbound channel adapter.

上面的代码配置了一个服务激活器、一个集成通道和一个入站通道适配器。

We’ll examine each of these component types in greater detail shortly. The @EnableIntegration annotation designates this class as a Spring Integration configuration.

我们将在不久之后对这些组件类型进行更详细的研究。@EnableIntegration注解将该类指定为Spring集成配置。

Let’s start our Spring Integration application context:

让我们开始我们的Spring Integration应用上下文。

public static void main(String... args) {
    AbstractApplicationContext context 
      = new AnnotationConfigApplicationContext(BasicIntegrationConfig.class);
    context.registerShutdownHook();
    
    Scanner scanner = new Scanner(System.in);
    System.out.print("Please enter q and press <enter> to exit the program: ");
    
    while (true) {
       String input = scanner.nextLine();
       if("q".equals(input.trim())) {
          break;
      }
    }
    System.exit(0);
}

The main method above starts up the integration context; it also accepts the “q” character input from the command line to exit the program. Let us examine the components in more detail.

上面的主方法启动了集成上下文;它还接受来自命令行的”q“字符输入以退出程序。让我们更详细地检查这些组件。

5. Spring Integration Components

5.Spring集成组件

5.1. Message

5.1.消息

The org.springframework.integration.Message interface defines the spring Message: the unit of data transfer within a Spring Integration context.

org.springframework.integration.Message 接口定义了spring Message:Spring Integration上下文中的数据传输单位。

public interface Message<T> {
    T getPayload();
    MessageHeaders getHeaders();
}

It defines accessors to two key elements:

它定义了两个关键元素的访问器。

  • Message headers, essentially a key-value container that can be used to transmit metadata, as defined in the org.springframework.integration.MessageHeaders class
  • The message payload, which is the actual data that is of value to be transferred — in our use-case, the video file is the payload

5.2. Channel

5.2.频道

A channel in Spring Integration (and indeed, EAI) is the basic plumbing in an integration architecture. It’s the pipe by which messages are relayed from one system to another.

Spring Integration(乃至EAI)中的通道是集成架构中的基本管道。它是消息从一个系统传递到另一个系统的管道。

You can think of it as a literal pipe through which an integrated system or process can push messages to (or receive messages from) other systems.

你可以把它看作是一个字面意义上的管道,一个集成的系统或流程可以通过它向其他系统推送消息(或接收消息)。

Channels in Spring Integration come in various flavors, depending on your need. They are largely configurable and usable out of the box, without any custom code, but should you have custom needs, there’s a robust framework available.

根据你的需要,Spring Integration中的通道有多种形式。它们在很大程度上是可配置的,可以开箱即用,不需要任何自定义代码,但如果你有自定义需求,也有一个强大的框架可以使用。

Point-to-Point (P2P) channels are used to establish 1-to-1 communication lines between systems or components. One component publishes a message to the channel so another can pick it up. There can be only one component at each end of the channel.

点对点(P2P)通道用于在系统或组件之间建立1对1的通信线路。一个组件将信息发布到信道上,以便另一个组件能够接收到它。通道的两端只能有一个组件。

As we have seen, configuring a channel is as simple as returning an instance of DirectChannel:

正如我们所看到的,配置一个通道就像返回一个DirectChannel的实例一样简单。

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

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

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

Here, we have defined three separate channels all identified by the name of their respective getter methods.

在这里,我们定义了三个独立的通道,都由它们各自的获取器方法的名称来标识。

Publish-Subscribe (Pub-Sub) channels are used to establish a one-to-many communication line between systems or components. This will allow us to publish to all 3 of the direct channels that we created earlier.

发布-订阅(Pub-Sub)通道是用来在系统或组件之间建立一对多的通信线路。这将使我们能够向我们先前创建的所有3个直接通道发布。

So following our example, we can replace the P2P channel with a pub-sub channel:

因此,按照我们的例子,我们可以用pub-sub通道代替P2P通道。

@Bean
public MessageChannel pubSubFileChannel() {
    return new PublishSubscribeChannel();
}

@Bean
@InboundChannelAdapter(value = "pubSubFileChannel", poller = @Poller(fixedDelay = "1000"))
public MessageSource<File> fileReadingMessageSource() {
    FileReadingMessageSource sourceReader = new FileReadingMessageSource();
    sourceReader.setDirectory(new File(INPUT_DIR));
    sourceReader.setFilter(new SimplePatternFileListFilter(FILE_PATTERN));
    return sourceReader;
}

We have now converted the inbound channel adapter to publish to a Pub-Sub channel. This will allow us to send the files that are being read from the source folder to multiple destinations.

我们现在已经将入站通道适配器转换为发布到Pub-Sub通道。这将使我们能够把从源文件夹中读取的文件发送到多个目的地。

5.3. Bridge

5.3.桥梁

A bridge in Spring Integration is used to connect two message channels or adapters if for any reason they can’t connect directly.

在Spring Integration中,如果两个消息通道或适配器由于某种原因不能直接连接,那么桥接器就是用来连接它们的。

In our case, we can use a bridge to connect our Pub-Sub channel to three different P2P channels (because P2P and Pub-Sub channels can’t be connected directly):

在我们的案例中,我们可以使用一个桥接器将我们的Pub-Sub通道连接到三个不同的P2P通道(因为P2P和Pub-Sub通道不能直接连接)。

@Bean
@BridgeFrom(value = "pubSubFileChannel")
public MessageChannel fileChannel1() {
    return new DirectChannel();
}

@Bean
@BridgeFrom(value = "pubSubFileChannel")
public MessageChannel fileChannel2() {
    return new DirectChannel();
}

@Bean
@BridgeFrom(value = "pubSubFileChannel")
public MessageChannel fileChannel3() {
    return new DirectChannel();
}

The above bean configuration now bridges the pubSubFileChannel to three P2P channels. The @BridgeFrom annotation is what defines a bridge and can be applied to any number of channels that need to subscribe to the Pub-Sub channel.

上面的bean配置现在将pubSubFileChannel与三个P2P通道连接起来。@BridgeFrom 注解是定义桥梁的东西,可以应用于需要订阅Pub-Sub通道的任何数量的通道。

We can read the above code as “create a bridge from the pubSubFileChannel to fileChannel1, fileChannel2, and fileChannel3 so that messages from pubSubFileChannel can be fed to all three channels simultaneously.”

我们可以将上述代码理解为 “从pubSubFileChannelfileChannel1、fileChannel2和fileChannel3创建一个桥梁,以便pubSubFileChannel的消息可以同时输入到所有三个通道。”

5.4. Service Activator

5.4.服务激活器

The Service Activator is any POJO that defines the @ServiceActivator annotation on a given method. This allows us to execute any method on our POJO when a message is received from an inbound channel, and it allows us to write messages to an outward channel.

服务激活器是任何在给定方法上定义了@ServiceActivator注释的POJO。这允许我们在收到入站通道的消息时执行我们POJO上的任何方法,并允许我们将消息写入出站通道。

In our example, our service activator receives a file from the configured input channel and writes it to the configured folder.

在我们的例子中,我们的服务激活器从配置的输入通道接收一个文件并将其写入配置的文件夹。

5.5. Adapter

5.5.适配器

The Adapter is an enterprise integration pattern-based component that allows one to “plug-in” to a system or data source. It is almost literally an adapter as we know it from plugging into a wall socket or electronic device.

适配器是一个基于企业集成模式的组件,允许人们 “插入 “到一个系统或数据源。它几乎就是我们所知的插在墙上的插座或电子设备上的适配器。

It allows reusable connectivity to otherwise “black-box” systems like databases, FTP servers and messaging systems such as JMS, AMQP, and social networks like Twitter. The ubiquity of the need to connect to these systems means that adapters are very portable and reusable (in fact there’s a small catalog of adapters, freely available and ready to use by anyone).

它允许可重复使用的连接到其他 “黑盒 “系统,如数据库、FTP 服务器和消息传递系统,如 JMS、AMQP 和 Twitter 等社交网络。连接这些系统的需求无处不在,这意味着适配器是非常可移植和可重用的(事实上,有一个小型的适配器目录,任何人都可以免费使用)。

Adapters fall into two broad categories — inbound and outbound.

适配器可分为两大类–入站和出站。

Let’s examine these categories in the context of the adapters in use in our sample scenario:

让我们在我们的示例方案中使用的适配器的背景下检查这些类别。

Inbound adapters, as we have seen, are used to bring in messages from the external system (in this case a filesystem directory).

入站适配器,正如我们所看到的,用于从外部系统(在这里是指文件系统目录)引入消息。

Our inbound adapter configuration consists of:

我们的入站适配器配置包括。

  • An @InboundChannelAdapter annotation that marks the bean configuration as an adapter — we configure the channel to which the adapter will feed its messages (in our case, an MPEG file) and a poller, a component which helps the adapter poll the configured folder at the specified interval
  • A standard Spring java configuration class that returns a FileReadingMessageSource, the Spring Integration class implementation that handles filesystem polling

Outbound adapters are used to send messages outwards. Spring Integration supports a large variety of out-of-the-box adapters for various common use cases.

出站适配器用于向外发送消息。Spring Integration支持大量的开箱即用的适配器,用于各种常见的使用情况。

6. Conclusion

6.结论

We have examined a basic use case with Spring Integration that demonstrates the java-based configuration of the library and reusability of the available components.

我们研究了一个使用Spring Integration的基本用例,展示了基于java的配置库和可用组件的重用性。

Spring Integration code is deployable as a standalone project within JavaSE as well as part of something larger in a Jakarta EE environment. While it doesn’t directly compete with other EAI-centric products and patterns like Enterprise Service Buses (ESBs), it is a viable, lightweight alternative to solving many of the same problems that ESBs were built to solve.

Spring Integration的代码可以作为JavaSE中的一个独立项目进行部署,也可以作为Jakarta EE环境中更大的项目的一部分。虽然它没有直接与其他以EAI为中心的产品和模式(如企业服务总线(ESB))竞争,但它是一个可行的、轻量级的替代方案,可以解决ESB所要解决的许多相同问题。

You can find the source code for this article in the Github project.

你可以在Github项目中找到这篇文章的源代码