2016-09-21 14 views
1

我在彈簧集成流量使用CharacterStreamReadingMessageSourceCharacterStreamReadingMessageSource.stdin()和EOF

IntegrationFlows.from(CharacterStreamReadingMessageSource.stdin()) 

它的工作原理。問題是,如果我管一個文件的過程:

cat file | java -jar app.jar 

java -jar app.jar < file 

一旦該文件已被讀取時,EOF不會傳播,標準輸入仍處於活動狀態,並且過程並沒有結束。我能做些什麼來使其表現如此?在命令行上手動輸入ctrl-Z按預期工作,關閉應用程序(Spring啓動應用程序,無網絡)。

回答

1

不幸的是,它不會在這種情況下工作;它專爲控制檯輸入而設計。

CharacterStreamReadingMessageSourceSystem.in換成BufferedReader並使用readLine()。由於readLine()塊,我們不想長時間綁定線程,我們檢查reader.ready(),如果沒有數據或流關閉,則返回false。

它應該提供一個阻止這個用例的選項,但是當與真正的控制檯一起使用時,它會永遠阻塞。

在此期間,您可以創建類的副本,改變 ...

@Override 
public Message<String> receive() { 
    try { 
     synchronized (this.monitor) { 
//   if (!this.reader.ready()) {   // remove this 
//    return null; 
//   } 
      String line = this.reader.readLine(); 
      if (line == null) {     // add this 
       ((ConfigurableApplicationContext) getApplicationContext()).close(); 
      } 
      return (line != null) ? new GenericMessage<String>(line) : null; 
     } 
    } 
    catch (IOException e) { 
     throw new MessagingException("IO failure occurred in adapter", e); 
    } 
} 

(刪除就緒檢查,並關閉在EOF範圍內)。

我打開了JIRA Issue

+0

只是想補充一點,這個解決方案的工作原理,但是人們應該知道,在更復雜的流程中,可能還有消息正在處理,並且會在消息流被關閉並且所有的bean被銷燬時丟失。不知道如何優雅地避免這種情況。因此,我最終沒有使用'CharacterStreamReadingMessageSource'(有一個修復),但創建了自己的'StdinReader'類,它從實現CommandLineRunner的類中調用,並且具有自動裝配的ThreadPoolExecutor以允許執行程序關閉。 – xbranko