我花了不少时间阅读有关Spring Integration的内容。今天我开始尝试框架。尽管我阅读了所有内容,但我仍然无法理解它的工作方式。我希望这里的人能让我回到正轨。
我定义了以下频道和端点:
<in:channel id="orderSource"/>
<in:service-activator input-channel="orderSource"
ref="defaultOrderService"
method="placeOrder"/>
由于频道是DirectChannel,我希望一切都在一个线程中发生,并在最后得到一个返回值。
placeOrder
方法如下所示:
@Override
public Order placeOrder(Order order) {
return order;
}
在我的主要方法中,我有:
MessageChannel input = context.getBean("orderSource", MessageChannel.class);
Message<Order> message = MessageBuilder.withPayload(new Order(123)).build();
MessagingTemplate messenger = new MessagingTemplate(input);
Message<?> result = messenger.sendAndReceive(message);
Object found = result.getPayload();
这一切都像魅力一样。 found
是服务激活器发回的顺序。
当我想通知一组订户已下订单时,我的问题就出现了。为简单起见,让我们同步这样做:
<in:channel id="orderSource"/>
<in:service-activator input-channel="orderSource"
output-channel="savedOrders"
ref="defaultOrderService"
method="validateOrder"/>
<in:publish-subscribe-channel id="savedOrders"/>
<in:outbound-channel-adapter channel="savedOrders"
ref="defaultOrderService"
method="notifyCustomerService"/>
<in:outbound-channel-adapter channel="savedOrders"
ref="defaultOrderService"
method="notifyShipmentManager"/>
<in:outbound-channel-adapter channel="savedOrders"
ref="defaultOrderService"
method="notifyWarehouseManager"/>
现在的问题是,当我调用sendAndReceive
时,输入通道应该期待什么呢?
我当前的代码块,我从未到达主线程的末尾。
我如何确保收到包含服务激活器结果的回复,因为它已将其传递给所有订阅者?
此外,我非常好奇当流中存在异步通道时,给定通道在返回值方面可以期待什么。我希望在事务结束时和新线程生成之前得到结果,但我不知道该怎么做。
有任何想法,建议或指导吗?
答案 0 :(得分:1)
据推测,您的“notify”方法返回null。如果是这种情况,则没有“回复”发送到MessagingTemplate
。
让最后一个返回订单,或者将<bridge/>
作为第四个订阅者添加到pub-sub频道。
通往无处的桥梁只是一座没有输出通道的桥梁。当消息到达产生回复的端点,并且没有output-channel
时,消息的replyChannel
标头用于将回复路由到发起者。
它也适用于异步通道,但在我提供指导之前,我需要了解您的要求。
另外,请考虑在主叫方使用Messaging Gateway,而不是自己构建消息并使用MessagingTemplate
。该框架不是将您的调用者暴露给消息传递基础结构,而是为您创建一个代理,它将负责所有这些并且您只需与POJI进行交互。
答案 1 :(得分:0)
我花了一些时间阅读,我发现这都是在消息或网关中配置回复通道,并使用桥接,就像Gary Rusell建议为我做的那样。
这是我的代码,正在运行:
<in:channel id="arrivals"/>
<in:service-activator input-channel="arrivals"
output-channel="validated"
ref="defaultOrderService"
method="validateOrder"/>
<in:channel id="validated"/>
<in:service-activator input-channel="validated"
output-channel="persisted"
ref="defaultOrderService"
method="placeOrder"/>
<in:publish-subscribe-channel id="persisted"/>
<in:channel id="replyChannel"/>
<in:bridge input-channel="persisted" output-channel="replyChannel"/>
<in:outbound-channel-adapter channel="persisted"
ref="defaultOrderService"
method="notifyCustomerService"/>
<in:outbound-channel-adapter channel="persisted"
ref="defaultOrderService"
method="notifyShipmentManager"/>
<in:outbound-channel-adapter channel="persisted"
ref="defaultOrderService"
method="notifyWarehouseManager"/>
<in:gateway id="orderService"
service-interface="codemasters.services.OrderService"
default-request-channel="arrivals"
default-reply-channel="replyChannel"/>
使用网关,现在看起来都很凉爽了:
OrderService service = context.getBean("orderService", OrderService.class);
Order result = service.validateOrder(new Order(4321));