如何在Spring Boot中管理一个无限进程?

3

我有一个无限循环的过程:

public class MyProcess {

    public void start() {
        while (true) {
            //process
        }
    }
}

当我开始使用Spring Boot时,我的第一步是在应用程序启动后从上下文中获取bean并手动启动流程:

@SpringBootApplication
public class MyApplication {

    public static void main(String[] args) {
        ApplicationContext applicationContext = SpringApplication.run(MyApplication.class, args);

        MyProcess myProcess = applicationContext.getBean(MyProcess.class);
        myProcess.start();
    }
}

这个方法可以工作,但似乎不是正确的做法,所以我实现了一个CommandLineRunner

@Component
public class MyRunner implements CommandLineRunner {

    @Autowired
    private MyProcess myProcess;

    @Override
    public void run(String... args) {
        this.myProcess.start();
    }
}

这几乎与以前相同,但这里的 SpringApplication#run 调用从未真正结束,这似乎也是错误的。我想这样想是正确的吗?
然后我尝试使用 Executor 自己管理,但为了捕获任何 Exception,我必须调用 Future#get,这导致了相同的阻塞状态。
相反,我现在在 CommandLineRunner#run 方法上使用 @Async 注释。
这似乎是最好的解决方案,因为任务启动后应用程序完成启动。任何Exception都将被捕获并记录,但由Spring创建的支持Executor会阻止应用程序关闭。
我假设有一种方法可以要求Spring终止Executor,以便整个应用程序可以退出,因为我正在使用Supervisor外部管理它。
这是正确的方法还是我缺少了一步?应用程序是否应该独立并在失败后重新启动进程?
1个回答

1
在主线程中执行一些工作。如果没有使用@Async,从main()调用myProcess.start()会有什么问题?当您完成工作后,只需离开MyProcess#start循环即可。

这是我最初做的事情,但我从未在任何示例中看到过,所以我不确定。那么 CommandLineRunner 的目的是什么? - Djon
@Djon 我有同样的问题。看起来这是一种在注入的bean中访问运行环境中的命令行参数的方法(在应用程序启动后)。我使用CommandLineRunner接口来创建命令行应用程序。 - ruX

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接