所有计时器完成后退出Spring Boot应用程序

时间:2017-07-27 09:59:24

标签: java spring-boot timertask

我在Spring Boot应用程序中运行了几个TimerTaskCommandLineRunner实施如下:

@SpringBootApplication
public class Main implements CommandLineRunner {

  private final Timer1 timer1;
  private final Timer2 timer2;

  static LocalDateTime startTime = LocalDateTime.now();

  public Main(Timer1 timer1, Timer2 timer2) {
    this.timer1 = timer1;
    this.timer2 = timer2;
  }

  public static void main(String[] args) {
    SpringApplication app = new SpringApplication(Main.class);
    app.setBannerMode(Banner.Mode.OFF);
    app.run(args);
  }

  @Override
  public void run(String... args) throws Exception {
    Timer t1 = new Timer();
    Timer t2 = new Timer();
    int tickTime = 10000;
    t1.scheduleAtFixedRate(this.timer1, 0, tickTime);
    t2.scheduleAtFixedRate(this.timer2, 5000, tickTime);
  }

}

以上成功安排了TimerTasks。但是在我的计时器任务中,我正在检查Main.startTime的当前时间来计算运行时间。如果分钟超过阈值,我将取消任务。

// Timer1.java
@Component
public class Timer1 extends GenericTimer {

  @Override
  public void run() {
    quitIfTimedOut();
  }

}

// Timer2.java
@Component
public class Timer2 extends GenericTimer {

  @Override
  public void run() {
    quitIfTimedOut();
  }

}

// GenericTimer.java
public abstract class GenericTimer extends TimerTask {

  protected void quitIfTimedOut() {
    LocalDateTime now = LocalDateTime.now();
    int timeoutThreshold = 1;
    long minutesSinceRunning = Main.startTime.until(now, ChronoUnit.MINUTES);

    if (minutesSinceRunning >= timeoutThreshold) {
      cancel();
    }
  }

}

到目前为止,它按照指定的标准正确取消了计时器任务。我的问题是,如果所有计时器任务都被取消,如何终止主线程?

我是否需要在Main.java中继续关注要取消的任务并致电SpringApplication.close( ... ),或者是否有更便捷,更健全的方法?

1 个答案:

答案 0 :(得分:0)

我发现的最佳方式是你提到的:

我注入ApplicationContext并执行以下操作以优雅地关闭应用程序:

int exit = SpringApplication.exit(this.applicationContext); // close gracefully before exit
System.exit(exit);

Spring关闭所有数据库连接等,然后强制退出应用程序。