简体   繁体   English

如何在 Reactive Spring Integration 中处理反应类型?

[英]How to handle reactive types within Reactive Spring Integration?

I'm playing a little with Reactive Spring Integration and I try to perform the following basic operation:我正在玩 Reactive Spring Integration 并尝试执行以下基本操作:

    @Override
    protected IntegrationFlowDefinition<?> buildFlow() {
        return from(someReactiveInboundChannelAdapter)
                .handle(new ReactiveMessageHandlerAdapter(flux -> flux.subscribe(System.out::println)));
    }

But this doesn't work since the framework won't recognize that flux is a Flux<?> instance.但这不起作用,因为框架不会识别flux是一个Flux<?>实例。 The framework treats this as a Message<?> and I don't know how and where can I start to write Reactor code.该框架将其视为Message<?> ,我不知道如何以及从何处开始编写 Reactor 代码。

That's correct.这是正确的。 The ReactiveMessageHandlerAdapter expects a lambda for the ReactiveMessageHandler which contract is: ReactiveMessageHandlerAdapter期望ReactiveMessageHandler的 lambda 合同是:

Mono<Void> handleMessage(Message<?> message);

I'm not sure what drove you to think that input has to be a Flux .我不确定是什么让您认为 input 必须是Flux

I assume your someReactiveInboundChannelAdapter is an extension of the MessageProducerSupport and does exactly subscribeToPublisher(Publisher<? extends Message<?>> publisher) logic.我假设您的someReactiveInboundChannelAdapterMessageProducerSupport的扩展,并且完全符合subscribeToPublisher(Publisher<? extends Message<?>> publisher)逻辑。 The point of this is to take data from the source in reactive manner, but still produce every event as a message to downstream channel.这样做的目的是以反应方式从源中获取数据,但仍将每个事件作为消息发送到下游通道。 So, that should become clear that a handle() is going to receive a message with a single item, not the whole Flux .因此,应该清楚handle()将接收包含单个项目的消息,而不是整个Flux

If you want to see the flow as a flux, consider to use a fluxTransform() operator.如果您想将流量视为通量,请考虑使用fluxTransform()运算符。

Also it is better to not subscribe yourself, but let to do that in the framework, when configuration and startup is over.此外,最好不要自己订阅,而是在配置和启动结束后在框架中订阅。

Technically you should not think about reactive types.从技术上讲,您不应该考虑反应类型。 You just need to configure a flow respectively and write a logic only for individual item: the framework does a reactive interaction for you.你只需要分别配置一个流程,只为单个项目编写逻辑:框架为你做一个反应式交互。 The Project Reactor is a library around Flux and Mono . Project Reactor 是一个围绕FluxMono的库。 That's where we talk about reactive types.这就是我们谈论反应类型的地方。 The Spring Integration is a messaging framework where its communication is done via messages. Spring Integration 是一个消息传递框架,它的通信是通过消息完成的。 And in the end for every single message it must not matter if interaction between endpoints is done in reactive manner or not.最后,对于每条消息,端点之间的交互是否以反应方式完成都无关紧要。 Therefore your processing logic can be free from reactive types.因此,您的处理逻辑可以不受反应类型的影响。

UDATE更新日期

If you want the full control of the Flux from that someReactiveInboundChannelAdapter , then you need to do like this:如果你想从那个someReactiveInboundChannelAdapter完全控制Flux ,那么你需要这样做:

    @Bean
    public Publisher<Message<Object>> reactiveFlow() {
          return IntegrationFlows.from(someReactiveInboundChannelAdapter)
          .toReactivePublisher();
    }

and then inject that Publisher whenever you need to use it.然后在需要使用它时注入该Publisher Then do Flux.from(publisher) and whatever reactive operators you need, including subscribe() .然后做Flux.from(publisher)和你需要的任何反应操作符,包括subscribe()

Some sample of that is here: https://github.com/spring-projects/spring-integration/blob/main/spring-integration-core/src/test/java/org/springframework/integration/dsl/reactivestreams/ReactiveStreamsTests.java这里有一些示例: https://github.com/spring-projects/spring-integration/blob/main/spring-integration-core/src/test/java/org/springframework/integration/dsl/reactivestreams/ReactiveStreamsTests .java

The IntegrationFlowAdapter cannot be used for this type of configuration since it cannot accept the IntegrationFlow as a result of the buildFlow() . IntegrationFlowAdapter不能用于这种类型的配置,因为它不能接受IntegrationFlow作为buildFlow()的结果。

The fluxTransform() can do that for you as well, though:不过, fluxTransform()也可以为您做到这一点:

.fluxTransform(flux -> flux.as(Mono::just))

So, the payload of downstream flow is going to be a Flux<Message<?>> , which you can handle yourself.因此,下游流的有效负载将是一个Flux<Message<?>> ,您可以自己处理。 The returned Mono from that fluxTransform() is going to be subscribed by the framework.从该fluxTransform()返回的Mono将由框架订阅。 That Flux of its value is your responsibility in the downstream flow.其价值的Flux是您在下游流程中的责任。 Then you can use the plain MessageHandler :然后你可以使用普通的MessageHandler

.handle(m -> ((Flux<Message<?>>) m.getPayload())....subscribe())

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM