# MongoDB 支持

## MongoDB 支持

2.1 版引入了对[MongoDB](https://www.mongodb.org/)的支持：一个“高性能、开源、面向文档的数据库”。

你需要在项目中包含此依赖项：

Maven

```
<dependency>
    <groupId>org.springframework.integration</groupId>
    <artifactId>spring-integration-mongodb</artifactId>
    <version>5.5.9</version>
</dependency>
```

Gradle

```
compile "org.springframework.integration:spring-integration-mongodb:5.5.9"
```

要下载、安装和运行 MongoDB，请参见[MongoDB 文档](https://www.mongodb.org/downloads)。

### 连接到 MongoDB

#### 阻塞还是反应？

从版本 5.3 开始， Spring 集成提供了对反应式 MongoDB 驱动程序的支持，以便在访问 MongoDB 时启用非阻塞 I/O。要启用反应性支持，请将 MongoDB 反应性流驱动程序添加到你的依赖项中：

Maven

```
<dependency>
    <groupId>org.mongodb</groupId>
    <artifactId>mongodb-driver-reactivestreams</artifactId>
</dependency>
```

Gradle

```
compile "org.mongodb:mongodb-driver-reactivestreams"
```

对于常规的同步客户机，你需要将其各自的驱动程序添加到依赖项中：

Maven

```
<dependency>
    <groupId>org.mongodb</groupId>
    <artifactId>mongodb-driver-sync</artifactId>
</dependency>
```

Gradle

```
compile "org.mongodb:mongodb-driver-sync"
```

它们都是`optional`框架中更好的终端用户选择支持。

要开始与 MongoDB 交互，你首先需要连接到它。 Spring 集成建立在另一个 Spring 项目[Spring Data MongoDB](https://projects.spring.io/spring-data-mongodb/)提供的支持之上。它提供了名为`MongoDatabaseFactory`和`ReactiveMongoDatabaseFactory`的工厂类，这简化了与 MongoDB 客户机 API 的集成。

|   |Spring 默认情况下提供的数据提供了阻塞的 MongoDB 驱动程序，但是你可以通过包括上述依赖项来 OPT 用于反应性使用。|
|---|---------------------------------------------------------------------------------------------------------------------------------------------|

#### 使用`MongoDatabaseFactory`

要连接到 MongoDB，你可以使用`MongoDatabaseFactory`接口的实现。

下面的示例展示了如何使用`SimpleMongoClientDatabaseFactory`:

爪哇

```
MongoDatabaseFactory mongoDbFactory =
        new SimpleMongoClientDatabaseFactory(com.mongodb.client.MongoClients.create(), "test");
```

XML

```
<bean id="mongoDbFactory" class="o.s.data.mongodb.core.SimpleMongoClientDatabaseFactory">
    <constructor-arg>
        <bean class="com.mongodb.client.MongoClients" factory-method="create"/>
    </constructor-arg>
    <constructor-arg value="test"/>
</bean>
```

`SimpleMongoClientDatabaseFactory`接受两个参数：一个`MongoClient`实例和一个指定数据库名称的`String`实例。如果需要配置`host`、`port`等属性，则可以使用底层`MongoClients`类提供的一个构造函数来传递这些属性。有关如何配置 MongoDB 的更多信息，请参见[Spring-Data-MongoDB](https://docs.spring.io/spring-data/data-mongo/docs/current/reference/html/)引用。

#### 使用`ReactiveMongoDatabaseFactory`

要使用 Reactive 驱动程序连接到 MongoDB，你可以使用`ReactiveMongoDatabaseFactory`接口的实现。

下面的示例展示了如何使用`SimpleReactiveMongoDatabaseFactory`:

爪哇

```
ReactiveMongoDatabaseFactory mongoDbFactory =
        new SimpleReactiveMongoDatabaseFactory(com.mongodb.reactivestreams.client.MongoClients.create(), "test");
```

XML

```
<bean id="mongoDbFactory" class="o.s.data.mongodb.core.SimpleReactiveMongoDatabaseFactory">
    <constructor-arg>
        <bean class="com.mongodb.reactivestreams.client.MongoClients" factory-method="create"/>
    </constructor-arg>
    <constructor-arg value="test"/>
</bean>
```

### MongoDB 消息存储

正如*Enterprise 整合模式*一书中所描述的，[消息存储](https://www.enterpriseintegrationpatterns.com/MessageStore.html)允许你持久化消息。在处理具有缓冲消息能力的组件（`QueueChannel`，`aggregator`，`resequencer`，以及其他）时，如果可靠性是一个问题，那么这样做是有用的。在 Spring 集成中，`MessageStore`策略还为[索赔检查](https://www.enterpriseintegrationpatterns.com/StoreInLibrary.html)模式提供了基础，这也在 EIP 中进行了描述。

Spring Integration 的 MongoDB 模块提供了`MongoDbMessageStore`，这是`MessageStore`策略（主要由索赔检查模式使用）和`MessageGroupStore`策略（主要由聚合器和重排序模式使用）的实现。

下面的示例将`MongoDbMessageStore`配置为使用`QueueChannel`和`aggregator`:

```
<bean id="mongoDbMessageStore" class="o.s.i.mongodb.store.MongoDbMessageStore">
    <constructor-arg ref="mongoDbFactory"/>
</bean>

<int:channel id="somePersistentQueueChannel">
    <int:queue message-store="mongoDbMessageStore"/>
<int:channel>

<int:aggregator input-channel="inputChannel" output-channel="outputChannel"
         message-store="mongoDbMessageStore"/>
```

前面的示例是一个简单的 Bean 配置，它需要一个`MongoDbFactory`作为构造函数参数。

`MongoDbMessageStore`通过使用 Spring 数据 mongo 映射机制，将`Message`扩展为具有所有嵌套属性的 mongo 文档。当你需要访问`payload`或`headers`以进行审计或分析（例如，针对存储的消息）时，它是有用的。

|   |`MongoDbMessageStore`使用自定义的`MappingMongoConverter`实现将`Message`实例存储为 MongoDB 文档，并且对`Message`的属性（`payload`和`header`值）有一些限制。|
|---|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|

从版本 5.1.6 开始，`MongoDbMessageStore`可以配置自定义转换器，这些转换器被传播到内部`MappingMongoConverter`实现中。有关更多信息，请参见`MongoDbMessageStore.setCustomConverters(Object…​ customConverters)`爪哇docs。

Spring Integration3.0 引入了`ConfigurableMongoDbMessageStore`。它实现了`MessageStore`和`MessageGroupStore`接口。这个类可以作为构造函数参数接收`MongoTemplate`，你可以使用它来配置自定义`WriteConcern`。另一个构造函数需要`MappingMongoConverter`和`MongoDbFactory`，这允许你为`Message`实例及其属性提供一些自定义转换。请注意，默认情况下，`ConfigurableMongoDbMessageStore`使用标准的 Java 序列化来编写和读取与 MongoDB 之间的`Message`实例（参见`MongoDbMessageBytesConverter`），并依赖于`MongoTemplate`中其他属性的默认值。它从提供的`MongoDbFactory`和`MappingMongoConverter`构建`MongoTemplate`。由`ConfigurableMongoDbMessageStore`存储的集合的默认名称是`configurableStoreMessages`。当消息包含复杂的数据类型时，我们建议使用此实现来创建健壮且灵活的解决方案。

#### MongoDB 通道消息存储

4.0 版引入了新的`MongoDbChannelMessageStore`。它是一个优化的`MessageGroupStore`，用于`QueueChannel`实例。使用`priorityEnabled = true`，你可以在`<int:priority-queue>`实例中使用它来实现持久消息的优先级顺序轮询。Priority MongoDB 文档字段是从`IntegrationMessageHeaderAccessor.PRIORITY`（`priority`）消息头填充的。

此外，所有 MongoDB`MessageStore`实例现在都有一个`sequence`字段，用于`MessageGroup`文档。`sequence`值是对同一个集合中的简单`sequence`文档执行`$inc`操作的结果，该集合是按需创建的。在`poll`操作中，当消息存储在相同的毫秒内时，`sequence`字段用于提供先进先出消息顺序（如果进行了配置，则在优先级内）。

|   |我们不建议对优先级和非优先级使用相同的`MongoDbChannelMessageStore` Bean，因为`priorityEnabled`选项适用于整个存储，<br/>但是，同样的`collection`可以用于两种`MongoDbChannelMessageStore`类型，由于存储中的消息轮询是经过排序的，并且使用 index.<br/>来配置该场景，因此可以从另一个扩展一个消息存储 Bean，如下例所示：|
|---|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|

```
<bean id="channelStore" class="o.s.i.mongodb.store.MongoDbChannelMessageStore">
    <constructor-arg name="mongoDbFactory" ref="mongoDbFactory"/>
</bean>

<int:channel id="queueChannel">
    <int:queue message-store="store"/>
</int:channel>

<bean id="priorityStore" parent="channelStore">
    <property name="priorityEnabled" value="true"/>
</bean>

<int:channel id="priorityChannel">
    <int:priority-queue message-store="priorityStore"/>
</int:channel>
```

#### MongoDB 元数据存储

Spring Integration4.2 引入了一种新的基于 MongoDB 的`MetadataStore`（参见[元数据存储](./meta-data-store.html#metadata-store)）实现。你可以使用`MongoDbMetadataStore`在应用程序重新启动期间维护元数据状态。你可以将这个新的`MetadataStore`实现与适配器一起使用，例如：

* [Feed](./feed.html#feed-inbound-channel-adapter)

* [File](./file.html#file-reading)

* [FTP](./ftp.html#ftp-inbound)

* [SFTP](./sftp.html#sftp-inbound)

要指示这些适配器使用新的`MongoDbMetadataStore`，请声明一个 Spring  Bean，其 Bean 名称为`metadataStore`。提要入站通道适配器自动拾取并使用声明的`MongoDbMetadataStore`。下面的示例展示了如何声明名称为`metadataStore`的 Bean:

```
@Bean
public MetadataStore metadataStore(MongoDbFactory factory) {
    return new MongoDbMetadataStore(factory, "integrationMetadataStore");
}
```

`MongoDbMetadataStore`还实现了`ConcurrentMetadataStore`，使其在多个应用程序实例之间可靠地共享，其中只允许一个实例存储或修改键值。多亏了 MongoDB 的担保，所有这些操作都是原子操作。

### MongoDB 入站通道适配器

MongoDB 入站通道适配器是一个轮询使用者，它从 MongoDB 读取数据，并将其作为`Message`有效负载发送。下面的示例展示了如何配置 MongoDB 入站通道适配器：

```
<int-mongodb:inbound-channel-adapter id="mongoInboundAdapter"
       channel="replyChannel"
       query="{'name' : 'Bob'}"
       entity-class="java.lang.Object"
       auto-startup="false">
		<int:poller fixed-rate="100"/>
</int-mongodb:inbound-channel-adapter>
```

如前面的配置所示，你可以通过使用`inbound-channel-adapter`元素并为各种属性提供值来配置 MongoDB 入站通道适配器，例如：

* `query`:一个 JSON 查询（参见[MongoDB 查询](https://www.mongodb.org/display/DOCS/Querying)）

* `query-expression`:对 JSON 查询字符串（如上面的`query`属性）或`o.s.data.mongodb.core.query.Query`实例求值的 spel 表达式。与`query`属性互斥。

* `entity-class`:有效载荷对象的类型。如果不提供，则返回`com.mongodb.DBObject`。

* `collection-name`或`collection-name-expression`:标识要使用的 MongoDB 集合的名称。

* `mongodb-factory`:对`o.s.data.mongodb.MongoDbFactory`实例的引用

* `mongo-template`:对`o.s.data.mongodb.core.MongoTemplate`实例的引用

* 在所有其他入站适配器中通用的其他属性（例如“channel”）。

|   |你不能同时设置`mongo-template`和`mongodb-factory`。|
|---|-----------------------------------------------------------|

前面的示例相对简单且静态，因为它具有`query`的文本值，并使用`collection`的默认名称。有时，你可能需要在运行时根据某些条件更改这些值。要做到这一点，使用它们的`-expression`等价物（`query-expression`和`collection-name-expression`），其中提供的表达式可以是任何有效的 spel 表达式。

此外，你可能希望对从 MongoDB 读取的已成功处理的数据进行一些后处理。例如；你可能希望在文档被处理后移动或删除该文档。你可以通过使用添加的事务同步特性 Spring Integration2.2 来实现这一点，如下例所示：

```
<int-mongodb:inbound-channel-adapter id="mongoInboundAdapter"
    channel="replyChannel"
    query-expression="new BasicQuery('{''name'' : ''Bob''}').limit(100)"
    entity-class="java.lang.Object"
    auto-startup="false">
        <int:poller fixed-rate="200" max-messages-per-poll="1">
            <int:transactional synchronization-factory="syncFactory"/>
        </int:poller>
</int-mongodb:inbound-channel-adapter>

<int:transaction-synchronization-factory id="syncFactory">
    <int:after-commit
        expression="@documentCleaner.remove(#mongoTemplate, payload, headers.mongo_collectionName)"
        channel="someChannel"/>
</int:transaction-synchronization-factory>

<bean id="documentCleaner" class="thing1.thing2.DocumentCleaner"/>

<bean id="transactionManager" class="o.s.i.transaction.PseudoTransactionManager"/>
```

下面的示例显示了前面示例中引用的`DocumentCleaner`:

```
public class DocumentCleaner {
    public void remove(MongoOperations mongoOperations, Object target, String collectionName) {
        if (target instanceof List<?>){
            List<?> documents = (List<?>) target;
            for (Object document : documents) {
                mongoOperations.remove(new BasicQuery(JSON.serialize(document)), collectionName);
            }
        }
    }
}
```

你可以使用`transactional`元素将你的 Poller 声明为事务性的。这个元素可以引用一个真正的事务管理器（例如，如果流的其他部分调用了 JDBC）。如果没有“真实”事务，则可以使用`o.s.i.transaction.PseudoTransactionManager`的实例，这是 Spring 的`PlatformTransactionManager`的实现，并且在没有实际事务的情况下启用 Mongo 适配器的事务同步功能。

|   |这样做不会使 MongoDB 本身具有事务性。<br/>它允许在成功之前或之后（提交）或失败之后（回滚）进行操作的同步。|
|---|----------------------------------------------------------------------------------------------------------------------------------------------------------------------|

一旦你的 Poller 是事务性的，你就可以在`transactional`元素上设置`o.s.i.transaction.TransactionSynchronizationFactory`的实例。a`TransactionSynchronizationFactory`创建`TransactionSynchronization`的实例。为了你的方便，我们公开了一个默认的基于 SPEL 的`TransactionSynchronizationFactory`，它允许你配置 SPEL 表达式，其执行将与事务协调（同步）。支持用于 before-commit、after-commit 和 after-rollback 事件的表达式，以及用于发送计算结果（如果有的话）的每个事件的通道。对于每个子元素，你可以指定`expression`和`channel`属性。如果只存在`channel`属性，则将接收到的消息作为特定同步场景的一部分发送到那里。如果只存在`expression`属性，并且表达式的结果是非空值，则生成一条结果为有效负载的消息，并将其发送到默认通道（`NullChannel`），并显示在日志中（在`DEBUG`级别上）。如果你希望计算结果转到特定的通道，请添加`channel`属性。如果表达式的结果是空的或无效的，则不会生成任何消息。

有关事务同步的更多信息，请参见[事务同步](./transactions.html#transaction-synchronization)。

从版本 5.5 开始，`MongoDbMessageSource`可以配置为`updateExpression`，它必须使用 MongoDB`update`语法计算为`String`，或者使用`org.springframework.data.mongodb.core.query.Update`实例。它可以作为 ABEV 描述的后处理过程的替代方案，它修改了从集合中获取的那些实体，因此在下一个轮询周期中不会再次从集合中提取它们（假设更新更改了查询中使用的一些值）。仍然建议使用事务来实现执行隔离和数据一致性，当同一集合的`MongoDbMessageSource`的几个实例在群集中使用时。

### MongoDB 更改入站通道适配器

从版本 5.3 开始，`spring-integration-mongodb`模块引入了`MongoDbChangeStreamMessageProducer`-用于 Spring data`MessageProducerSupport`API 的反应式`MessageProducerSupport`实现。这个组件生成一个`Flux`的消息，默认情况下以`body`的`ChangeStreamEvent`作为有效负载，并生成一些与流相关的更改头（参见`MongoHeaders`）。建议将此`MongoDbChangeStreamMessageProducer`与`FluxMessageChannel`合并为`outputChannel`，用于按需订阅和下游事件消费。

此通道适配器的 Java DSL 配置可能如下所示：

```
@Bean
IntegrationFlow changeStreamFlow(ReactiveMongoOperations mongoTemplate) {
    return IntegrationFlows.from(
            MongoDb.changeStreamInboundChannelAdapter(mongoTemplate)
                    .domainType(Person.class)
                    .collection("person")
                    .extractBody(false))
            .channel(MessageChannels.flux())
            .get();
}
```

当`MongoDbChangeStreamMessageProducer`被停止，或者订阅在下游被取消，或者 MongoDB 变更流产生`OperationType.INVALIDATE`时，`Publisher`就完成了。可以再次启动通道适配器，并创建一个新的`Publisher`源数据，并在`MessageProducerSupport.subscribeToPublisher(Publisher<? extends Message<?>>)`中自动订阅它。如果需要使用来自其他地方的变更流事件，则可以重新配置此通道适配器，以便在两次启动之间提供新的选项。

有关变更流支持的更多信息，请参见 Spring Data MongoDB[文件](https://docs.spring.io/spring-data/mongodb/docs/current/reference/html/#change-streams)。

### MongoDB 出站通道适配器

MongoDB 出站通道适配器允许你将消息有效负载写入 MongoDB 文档存储，如下例所示：

```
<int-mongodb:outbound-channel-adapter id="fullConfigWithCollectionExpression"
	collection-name="myCollection"
	mongo-converter="mongoConverter"
	mongodb-factory="mongoDbFactory" />
```

如前面的配置所示，你可以通过使用`outbound-channel-adapter`元素来配置 MongoDB 出站通道适配器，该元素为各种属性提供值，例如：

* `collection-name`或`collection-name-expression`:标识要使用的 MongoDB 集合的名称。

* `mongo-converter`:对`o.s.data.mongodb.core.convert.MongoConverter`实例的引用，该实例有助于将原始 Java 对象转换为 JSON 文档表示。

* `mongodb-factory`:引用`o.s.data.mongodb.MongoDbFactory`的实例。

* `mongo-template`:引用`o.s.data.mongodb.core.MongoTemplate`的实例。注意：不能同时拥有 Mongo-Template 和 MongoDB-Factory 集。

* 在所有其他入站适配器中通用的其他属性（例如“channel”）。

前面的示例相对简单且静态，因为它具有`collection-name`的文本值。有时，你可能需要在运行时根据某些条件更改这个值。要做到这一点，请使用`collection-name-expression`，其中提供的表达式是任何有效的 SPEL 表达式。

### MongoDB 出站网关

5.0 版引入了 MongoDB 出站网关。它允许你通过向数据库的请求通道发送消息来查询数据库。然后，网关将响应发送到应答通道。你可以使用消息有效负载和标题来指定查询和集合名称，如下例所示：

Java DSL

```
@SpringBootApplication
public class MongoDbJavaApplication {

    public static void main(String[] args) {
        new SpringApplicationBuilder(MongoDbJavaApplication.class)
            .web(false)
            .run(args);
    }

    @Autowired
    private MongoDbFactory;

    @Autowired
    private MongoConverter;

    @Bean
    public IntegrationFlow gatewaySingleQueryFlow() {
        return f -> f
                .handle(queryOutboundGateway())
                .channel(c -> c.queue("retrieveResults"));
    }

    private MongoDbOutboundGatewaySpec queryOutboundGateway() {
        return MongoDb.outboundGateway(this.mongoDbFactory, this.mongoConverter)
                .query("{name : 'Bob'}")
                .collectionNameFunction(m -> m.getHeaders().get("collection"))
                .expectSingleResult(true)
                .entityClass(Person.class);
    }

}
```

Kotlin DSL

```
class MongoDbKotlinApplication {

    fun main(args: Array<String>) = runApplication<MongoDbKotlinApplication>(*args)

    @Autowired
    lateinit var mongoDbFactory: MongoDatabaseFactory;

    @Autowired
    lateinit var mongoConverter: MongoConverter;

    @Bean
    fun gatewaySingleQueryFlow() =
    integrationFlow {
        handle(queryOutboundGateway())
        channel { queue("retrieveResults") }
    }

    private fun queryOutboundGateway(): MongoDbOutboundGatewaySpec {
        return MongoDb.outboundGateway(this.mongoDbFactory, this.mongoConverter)
            .query("{name : 'Bob'}")
            .collectionNameFunction<Any> { m -> m.headers["collection"] as String }
            .expectSingleResult(true)
            .entityClass(Person::class.java)
    }

}
```

Java

```
@SpringBootApplication
public class MongoDbJavaApplication {

    public static void main(String[] args) {
        new SpringApplicationBuilder(MongoDbJavaApplication.class)
            .web(false)
            .run(args);
    }

    @Autowired
    private MongoDbFactory mongoDbFactory;

    @Bean
    @ServiceActivator(inputChannel = "requestChannel")
    public MessageHandler mongoDbOutboundGateway() {
        MongoDbOutboundGateway gateway = new MongoDbOutboundGateway(this.mongoDbFactory);
        gateway.setCollectionNameExpressionString("'myCollection'");
        gateway.setQueryExpressionString("'{''name'' : ''Bob''}'");
        gateway.setExpectSingleResult(true);
        gateway.setEntityClass(Person.class);
        gateway.setOutputChannelName("replyChannel");
        return gateway;
    }

    @Bean
    @ServiceActivator(inputChannel = "replyChannel")
    public MessageHandler handler() {
        return message -> System.out.println(message.getPayload());
    }
}
```

XML

```
<int-mongodb:outbound-gateway id="gatewayQuery"
    mongodb-factory="mongoDbFactory"
    mongo-converter="mongoConverter"
    query="{firstName: 'Bob'}"
    collection-name="myCollection"
    request-channel="in"
    reply-channel="out"
    entity-class="org.springframework.integration.mongodb.test.entity$Person"/>
```

你可以在 MongoDB 出站网关中使用以下属性：

* `collection-name`或`collection-name-expression`:标识要使用的 MongoDB 集合的名称。

* `mongo-converter`:对`o.s.data.mongodb.core.convert.MongoConverter`实例的引用，该实例有助于将原始 Java 对象转换为 JSON 文档表示。

* `mongodb-factory`:引用`o.s.data.mongodb.MongoDbFactory`的实例。

* `mongo-template`:引用`o.s.data.mongodb.core.MongoTemplate`的实例。注意：不能同时设置`mongo-template`和`mongodb-factory`。

* `entity-class`:在 MongoTemplate 中传递给`find(..)`和`findOne(..)`方法的实体类的完全限定名。如果不提供此属性，则默认值为`org.bson.Document`。

* `query`或`query-expression`:指定 MongoDB 查询。有关更多查询示例，请参见[MongoDB 文档](https://www.mongodb.org/display/DOCS/Querying)。

* `collection-callback`:引用`org.springframework.data.mongodb.core.CollectionCallback`的实例。优选的实例是`o.s.i.mongodb.outbound.MessageCollectionCallback`自 5.0.11 起带有请求消息上下文的实例。有关更多信息，请参见其 Javadocs。注意：不能同时拥有`collection-callback`和任何查询属性。

作为`query`和`query-expression`属性的替代选项，你可以通过使用`collectionCallback`属性作为对`MessageCollectionCallback`功能接口实现的引用来指定其他数据库操作。下面的示例指定了一个 Count 操作：

```
private MongoDbOutboundGatewaySpec collectionCallbackOutboundGateway() {
    return MongoDb.outboundGateway(this.mongoDbFactory, this.mongoConverter)
            .collectionCallback((collection, requestMessage) -> collection.count())
            .collectionName("myCollection");
}
```

### MongoDB 反应通道适配器

从版本 5.3 开始，提供了`ReactiveMongoDbStoringMessageHandler`和`ReactiveMongoDbMessageSource`实现。它们基于 Spring 数据中的`ReactiveMongoOperations`，并且需要一个`org.mongodb:mongodb-driver-reactivestreams`依赖项。

`ReactiveMongoDbStoringMessageHandler`是`ReactiveMessageHandler`的一种实现，当集成流定义中涉及到反应流组合时，它在框架中得到原生支持。有关更多信息，请参见[reactiveMessageHandler](./reactive-streams.html#reactive-message-handler)。

从配置角度来看，与许多其他标准通道适配器没有区别。例如，对于 Java DSL，这样的通道适配器可以使用如下方式：

```
@Bean
public IntegrationFlow reactiveMongoDbFlow(ReactiveMongoDatabaseFactory mongoDbFactory) {
    return f -> f
            .channel(MessageChannels.flux())
            .handle(MongoDb.reactiveOutboundChannelAdapter(mongoDbFactory));
}
```

在这个示例中，我们将通过提供的`ReactiveMongoDatabaseFactory`连接到 MongoDB，并将来自请求消息的数据存储到具有`data`名称的默认集合中。实际操作将通过内部创建的`ReactiveStreamsConsumer`中的反应流组合按需执行。

该`ReactiveMongoDbMessageSource`是基于所提供的`ReactiveMongoDatabaseFactory`或`ReactiveMongoOperations`和 MongoDB 查询（或表达式）的`ReactiveMongoDbMessageSource`实现的`AbstractMessageSource`，根据`expectSingleResult`选项调用`entityClass`或`findOne()`的操作，用预期的`entityClass`类型转换查询结果。当`Publisher`（`Flux`或`Mono`根据`expectSingleResult`选项）在产生的消息的有效负载被订阅时，按需执行查询执行和结果评估。当下游使用 Splitter 和`FluxMessageChannel`时，框架可以自动订阅这样的有效负载（本质上是`flatMap`）。否则，目标应用程序有责任在下游端点中订阅到已投票的发布程序。

使用 Java DSL，这样的通道适配器可以进行如下配置：

```
@Bean
public IntegrationFlow reactiveMongoDbFlow(ReactiveMongoDatabaseFactory mongoDbFactory) {
    return IntegrationFlows
            .from(MongoDb.reactiveInboundChannelAdapter(mongoDbFactory, "{'name' : 'Name'}")
                            .entityClass(Person.class),
                    c -> c.poller(Pollers.fixedDelay(1000)))
            .split()
            .channel(c -> c.flux("output"))
            .get();
}
```

从版本 5.5 开始，`ReactiveMongoDbMessageSource`可以配置为`updateExpression`。它具有与阻塞`MongoDbMessageSource`相同的功能。有关更多信息，请参见[MongoDB 入站通道适配器](#mongodb-inbound-channel-adapter)和`AbstractMongoDbMessageSourceSpec`Javadocs。