Как закрыть приложение командной строки Spring Boot

Я создаю java-приложение командной строки, используя Spring Boot, чтобы заставить его работать быстро.

Приложение загружает файлы разных типов (например, CSV) и загружает их в базу данных Cassandra. Он НЕ использует веб-компоненты, это не веб-приложение.

Проблема, с которой я столкнулась, заключается в том, чтобы остановить приложение, когда работа выполнена. Я использую интерфейс Spring CommandLineRunner с @Component для запуска задач, как показано ниже, но когда работа завершена, приложение не останавливается, оно по какой-то причине работает, и я не могу найти способ остановите его.

@Component
public class OneTimeRunner implements CommandLineRunner {

    @Autowired
    private CassandraOperations cassandra;

    @Autowired
    private ConfigurableApplicationContext context;

    @Override
    public void run(String... args) throws Exception {
        // do some work here and then quit
        context.close();
    }
}

UPDATE: проблема кажется spring-cassandra, поскольку в проекте ничего нет. Кто-нибудь знает, почему он поддерживает потоки, запущенные в фоновом режиме, которые препятствуют тому, чтобы приложение остановилось?

UPDATE: проблема исчезла, обновив последнюю версию Spring.

Ответы

Ответ 1

Ответ зависит от того, что он все еще делает. Вероятно, вы можете узнать с дампом потока (например, с помощью jstack). Но если это что-то, что было начато с помощью Spring, вы можете использовать ConfigurableApplicationContext.close(), чтобы остановить приложение в своем методе main() (или в CommandLineRunner).

Ответ 2

Я нашел решение. Вы можете использовать это:

public static void main(String[] args) {
    SpringApplication.run(RsscollectorApplication.class, args).close();
    System.out.println("done");
}

Просто используйте .close при запуске.

Ответ 3

Я также встретил эту проблему в своем текущем проекте (spring приложение для загрузки). Мое решение:

// releasing all resources
((ConfigurableApplicationContext) ctx).close();
// Close application
System.exit(0);

context.close() не останавливайте наше консольное приложение, оно просто освобождает ресурсы.

Ответ 4

Это комбинация @EliuX ответа @Quan Vo. Спасибо вам всем!

Основным отличием является то, что я передаю код ответа SpringApplication.exit(context) в качестве параметра в System.exit(), поэтому, если есть ошибка, закрывающая контекст Spring, который вы заметите.

SpringApplication.exit() закроет контекст Spring.

System.exit() закроет приложение.

@Component
public class OneTimeRunner implements CommandLineRunner {

    @Autowired
    private ConfigurableApplicationContext context;

    @Override
    public void run(String... args) throws Exception { 
       System.exit(SpringApplication.exit(context));
    }
}

Ответ 5

Используйте org.springframework.boot.SpringApplication#exit. Например.

@Component
public class OneTimeRunner implements CommandLineRunner {

    @Autowired
    private ConfigurableApplicationContext context;

    @Override
    public void run(String... args) throws Exception { 
        SpringApplication.exit(context);
    }
}