由spring-integration-rmi引申出的spring integration和spring remoting的对比
spring-integration-rmi适用于什么样的场景?RMI技术使两个系统通过接口的远程方法调用连接起来,当接口需要返回值时,RMI会同步地阻塞,直到收到远端系统地返回值(或者超时)。但spring-integration-rmi却并不尽然,它基于spring-integration,通讯介质是消息(Message),任何要传递地东西先封装成消息,再传递给一个Channel,然后一个rmi的gateway对接到这个channel,将消息通过RMI传递出去,获得返回值后,将返回的消息(Message)再传给一个Channel,发起方需要额外再写一个独立的outbound-channel-adapter处理这些返回消息。大家注意到没有,这个过程是异步的!不适用于发起调用后根据返回值做后续处理的场景。我有点迷惑了。Google搜索“spring-integration RPC”,第四条是来自springsource官方论坛的帖子“Spring remoting via spring integration - Am I missing some concepts?”解答了我的疑惑,现全文翻译如下:
Matt Di(楼主):
大家好:
在我接触spring integration时,我对它涉及到的概念还有很有把握的,它照例来源于spring。
我以为SI(spring integration的缩写 译者)是基于spring remoting的一个抽象层,比如它既可以处理同步也可以处理异步服务调用。更进一步的,我还假定SI支持消息(message)和服务巴士(service bus)的配置。但是在实际使用中,我遇到了预想不到的困难。
我想要的目标是:
客户端通过JMS远程调用组件异步地调用服务接口(ServiceInterface)(使用队列(Queue),因为那样的话发送和接收的过程可以是事务性的)。服务端接收服务调用(service call),将之委托给具体接口实现类去处理。
客户端暴露的接口如下所示:
?
?
中央平台包含所有的暴露接口的实现。毫不奇怪的,当检测一个通用接口的实现类时,代码看起来象这样:
?
?
?简便起见,这里只有一个队列,它负责逻辑任务(在这有例子中,异步地处理一个特定的服务)。
我如何才能继承服务端的配置确信每个方法如log,process和replication被一个合适的服务实现处理?
SI支持包裹多个参数(@see replication(Long id, Dto dto))到一个消息的payload里吗?
感谢任何高见
?
oleg.zhurakousky(高级会员、Spring团队):
一个通常被误解的概念就是通常意义上的服务(services)(非SI关联)事实上就是人们趋向将一个Java类作为一个服务。恕我直言(IMHO,有意思的缩写 译者),这是错误的。Java类是一些相互关联的服务的集合,服务呢,就是一个方法。因此在你有一个类拥有多个方法的用例下,当然拥有多个service-activator引用到同一个bean(通过'ref'属性)是一点问题也没有的,这些方法属性映射每个servcie-activator到一个特定服务。
?
Matt Di(楼主):
Oleg你好,
你的解释我知道了。问题是我如何才能使用多个service activator呢?当我试验我的SI例子时发现了一个奇怪的现象。
当调用log10次,毫无预料的,5次方法log,5次方法process调用,使用如下多service activator配置:
?
?
当看到payload类型匹配时,?这是一个对我来说没有预料到的行为但是是可以理解的。SI试图匹配payload类型到参数类型,就像Mark提到的。为了使配置干净,我仅仅使用了一个jms队列,处理两个系统之间的通讯。
我如何配置service提供者才能确信对于每个外部的gateway接口和它定义的方法来说,队列的pipelined消息会被某个类的合适的方法处理。
?
Mark Fisher(论坛高级会员、Spring团队):
你可以得到的是这里有有个默认的“round robin”负载均衡。It's actually invoking those 2 consumers each every other time a Message arrives.(Mark啊,您老的意思我懂,翻译不出,咋办? 译者)
如果你想要对单个消费者动态类型匹配,这里有两个选择:1)在<service-activator/>里准备一个method属性,确信所有的处理方法拥有相同的名字或者2)不管方法名,通过返回类型匹配所有public方法。对于fine-tuning的选择#2,假设你拥有类的控制权,你也可以添加@ServiceActivator注解到你想要将之作为后候选者的方法上。
?
oleg.zhurakousky(论坛高级会员、Spring团队):
然而,看着你的类,Mark所说的动态类型匹配看起来并不像是你的选择,这意味着你不得不将每个service-activator绑定到一个没有依赖的input-channel上同时将一个router方到它前面:
?
input-channel -> service-activator / Gateway -> request-channel -> router \ input-channel -> service-activator?router可以基于方法名字路由,这个可以在Message History中得到,你可以在Loan Broker的例子里看看如何从Message History中获取gateway的方法名字 -?http://blog.springsource.com/2010/03...tation-part-1/
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?