弹簧启动执行器关闭不会终止无限循环

时间:2019-07-18 10:25:52

标签: java spring spring-boot shutdown spring-boot-actuator

在我的Spring Boot应用程序中,我有一个组件,该组件的方法可以在下面的无限循环中运行某些工作,实际上它会检查db中的某些数据:

while(true) {// DOES SOME JOB}

这是我的Spring Boot应用程序的应用入口点:

@SpringBootApplication
public class Application implements CommandLineRunner {

    private final Service service;

    @Autowired
    public Application(Service service) {
        this.service = service;
    }

    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }

    @Override
    public void run(String... args) {
        service.run();
    }
}

并且启用了执行器的关闭端点,因此我可以通过以下方式终止应用程序:curl -X POST localhost:8080/actuator/shutdown,在我的情况下,它仅终止spring上下文,但循环仍在运行...是否有可能像{ {1}}可以(甚至具有无限循环)。

注意::我知道可以使用shutdown链接编写自己的上下文感知终结点,并且只要有人请求终结点,我就可以关闭spring上下文和 Syste.exit(0)(它肯定会终止循环),甚至为无限循环提供布尔标志,但是默认情况下spring是否提供了某些东西,比如说更优雅?

2 个答案:

答案 0 :(得分:1)

您可以使用@PreDestroy批注优雅地关闭应用程序

@PreDestroy
public void destroy() {
 System.out.println("destroy");
}

因此,当您使用ctrl + C终止应用程序时,循环也将被终止。

答案 1 :(得分:1)

对于执行器,其“关闭”方法将关闭应用程序上下文。

尽管bean是由spring管理的,但是由于其某些方法存在无限循环,因此spring不能真正知道这一点,也无法真正打破此循环。

Spring确实管理Bean的生命周期,确实就像@Shruti Gupta所说的那样,您可以创建一个带有@PreDestroy批注的批注方法,以便Spring可以调用它,但是再次,您必须实现打破循环的逻辑。

以下是一些可能对您有用的示例:

@Component
public class MyBean {
    private boolean shouldKeepCheckingDB = true; // consider volatile as well if you need it, kind of out of scope for this question, but might be useful

    public void checkDB() {
        while(shouldKeepCheckingDB) { // instead of while(true)
            // check the database
        }
    }

    @PreDestroy
    void stop() {
        this.shouldKeepCheckingDB = false;
    } 
}