2014-10-17 76 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