Spring Integration:发布订阅频道。它是异步的吗?

时间:2013-09-03 15:35:47

标签: spring publish-subscribe

我在入站网关接收到一个String消息之后使用发布 - 订阅通道,并将其并行发送到记录器以记录消息,并转换为变换器以转换消息。我希望这两种活动同时发生。

我的问题非常简单 - spring集成中的发布订阅频道是否并行发送消息给它的子文件?

以下是spring-integration-context.xml源代码片段。

<int:gateway id="gateway" service-interface="com.test.Gateway">
    </int:gateway>
<int:publish-subscribe-channel id="publishsubscribechannel" />

<int:service-activator input-channel="publishsubscribechannel"
        method="transformEvent" ref="transformer" output-channel="transformerreplychannel">
</int:service-activator>
<int:service-activator input-channel="publishsubscribechannel"
        method="logMessage" ref="logger">
</int:service-activator>

此处变换器和记录器是publishsubscribechannel的2个订户。在此设置中,默认情况下,从网关流向记录器和变换器的消息是异步发生的......或者我需要做一些其他配置才能实现相同的目的。

3 个答案:

答案 0 :(得分:7)

...或使用JavaConfig

@Bean
public MessageChannel publishsubscribechannel() {

return new PublishSubscribeChannel(executor());
} 

@Bean
public ThreadPoolTaskExecutor executor() {

ThreadPoolTaskExecutor pool = new ThreadPoolTaskExecutor();
pool.setCorePoolSize(10);
pool.setMaxPoolSize(10);
pool.setWaitForTasksToCompleteOnShutdown(true);
return pool;
}

答案 1 :(得分:5)

默认情况下,它按顺序运行。所以在你的情况下,它将是 transformer ,然后是 logger 。如果要并行运行它,则需要指定task-executor

<int:publish-subscribe-channel id="publishsubscribechannel" task-executor="executor" />
...
<task:executor id="executor" pool-size="10" />

通过使用task-executor,消息处理是异步执行的。

答案 2 :(得分:4)

来自Spring Integration文档

<强> PublishSubscribeChannel

PublishSubscribeChannel实现广播发送给它的所有订阅处理程序的任何消息。这通常用于发送主要角色是通知的事件消息,而不是通常用于由单个处理程序处理的文档消息。请注意,PublishSubscribeChannel仅用于发送。由于它在调用其send(Message)方法时直接向其订阅者广播,因此消费者无法轮询消息(它没有实现PollableChannel,因此没有receive()方法)。相反,任何订阅者本身必须是MessageHandler,并且将依次调用订阅者的handleMessage(Message)方法。

在3.0版之前,在没有订阅者的PublishSubscribeChannel上调用send方法返回false。与MessagingTemplate一起使用时,抛出了MessageDeliveryException。从3.0版开始,行为已发生变化,如果至少存在最小订户(并成功处理该消息),则始终认为发送成功。可以通过设置minSubscribers属性来修改此行为,该属性默认为0.

[注意]注意 如果使用TaskExecutor,则只有正确数量的订户才会用于此确定,因为消息的实际处理是异步执行的。

请注意注意事项。 它确实提到如果使用TaskExecutor,消息处理将是异步的。

所以,是的,您必须为此添加一个TaskExecutor才能异步。