Spring boot CharacterStreamReadingMessageSource.stdin()和EOF
我正在spring集成流中使用Spring boot CharacterStreamReadingMessageSource.stdin()和EOF,spring-boot,spring-integration,Spring Boot,Spring Integration,我正在spring集成流中使用CharacterStreamReadingMessageSource: IntegrationFlows.from(CharacterStreamReadingMessageSource.stdin()) 它起作用了。问题是,如果我将文件通过管道传输到进程: cat file | java -jar app.jar 或 java-jarapp.jar
CharacterStreamReadingMessageSource
:
IntegrationFlows.from(CharacterStreamReadingMessageSource.stdin())
它起作用了。问题是,如果我将文件通过管道传输到进程:
cat file | java -jar app.jar
或
java-jarapp.jar
读取文件后,EOF不会传播,stdin仍处于活动状态,进程不会结束。我能做些什么让它这样做吗?在命令行上手动输入
ctrl-Z
,按预期工作,关闭应用程序(Spring boot应用程序,无web)。不幸的是,它在该场景中不起作用;它是为控制台输入而设计的
CharacterStreamReadingMessageSource
将系统包装在BufferedReader
中,并使用readLine()
。由于readLine()
阻塞,并且我们不想长时间占用线程,因此我们检查reader.ready()
,如果没有数据或流关闭,它将返回false
它可能会为这个用例提供一个阻塞选项,但是当与真正的控制台一起使用时,它将永远阻塞
同时,您可以创建类的副本并更改receive()
@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);
}
}
@覆盖
公共消息接收(){
试一试{
已同步(此.monitor){
//如果(!this.reader.ready()){//删除此
//返回null;
// }
String line=this.reader.readLine();
如果(line==null){//添加此
((ConfigurableApplicationContext)getApplicationContext()).close();
}
返回(行!=null)?新建GenericMessage(行):null;
}
}
捕获(IOE异常){
抛出新的MessaginException(“适配器中发生IO故障”,e);
}
}
(删除就绪检查,并在EOF关闭上下文)
我打开了一个。只是想补充一点,这个解决方案是有效的,但是人们应该意识到,在更复杂的流中,可能会有消息仍在被处理并通过流,当上下文关闭并且所有bean都被销毁时,这些消息将丢失。不知道如何优雅地避免这种情况。因此,我最终没有使用字符streamreadingmessagesource
(有一个补丁),而是创建了我自己的StdinReader
类,该类从实现命令行运行程序的类调用,并将ThreadPoolExecutor
自动连接以允许执行器关闭。
@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);
}
}