2014-10-17 50 views
3

我有一个异步网关与异步执行程序和错误通道定义。还有一个处理异常的服务激活器。弹簧集成异步网关与错误通道导致线程停止

<int:gateway id="myGateway" 
      service-interface="me.myGateway" 
      default-request-channel="requestChannel" 
      async-executor="taskScheduler" 
      error-channel="errorChannel"/> 

<int:service-activator ref="errorChannelMessageHandler" method="handleFailedInvocation" 
         input-channel="errorChannel"/> 
public interface MyGateway { 
    Future<Object> send(Message message); 
} 

@Component 
public class ErrorChannelMessageHandler { 
    @ServiceActivator 
    public Object handleFailedInvocation(MessagingException exception) { 
     // do some stuff here 
     return null; 
    } 
} 

当正在抛出异常,线程块,等待在临时应答的应答信道的网关已经建立。

如何防止线程阻塞以及何时抛出异常以使错误通道服务激活器处理消息并执行一些自定义逻辑?

后来编辑: 我使用SI 3.0.3.RELEASE 当错误信道被用于网关所定义,如果发生异常,将调用此线(无250从MessagingGatewaySupport)errorFlowReply = this.messagingTemplate.sendAndReceive (this.errorChannel,errorMessage),它将在新创建的临时回复通道(来自MessagingTemplate的第352-367行)上执行阻止接收。我的服务激活器是否为负责在这个新创建的临时通道上发布消息的错误通道,所以线程不会阻塞接收?

回答

1

删除错误通道,以便将原始异常添加到Future,以便get()将传播它。

如果您想对错误流执行某些操作,请从错误流中引发异常,以便在Future中可用,或将reply-timeout设置为0.但是,在此情况下,您的Future将永远不会获得值或例外。

+0

长话短说:我的SI链连接到RabbitMQ并发布消息。当兔子连接关闭时,将抛出AmqpConnectException。在这种情况下,我想要做的是获取消息并将它们保存在某处(db,本地文件)。这是错误通道有用的地方,因为在服务激活器中,我将执行此操作。如果我删除错误频道,我该怎么做?未来的get()可能并不总是被调用,因为有时候我想要一个答案,有时候我只是做一个难忘的事情。 – 2014-10-17 12:52:55

+0

另一个问题:如果我删除错误通道,那么如果我无法正确使用它,那么为网关设置此属性有什么意义?或者我在这里错过了一些东西。谢谢 – 2014-10-17 12:53:59

+0

您可以使用错误通道,但错误流必须返回结果或抛出异常(或如我所说,将'reply-timeout'设置为0)。除非你有进一步的异步切换,否则它不会影响“良好”的流程 - 只有在线程返回到网关时才会启动应答超时。 – 2014-10-17 12:58:20