2014-10-12 6 views
14

Я создаю java-приложение командной строки, используя Spring Boot, чтобы заставить его работать быстро.Как закрыть приложение командной строки 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, так как нет ничего в проекте. Кто-нибудь знает, почему он поддерживает потоки, запущенные в фоновом режиме, которые предотвращают остановку приложения?

ОБНОВЛЕНИЕ: проблема исчезла путем обновления до последней версии весенней загрузки.

+0

Любое решение этого вопроса? Это случается с обычным весенним ботинком (без кассандры) – ACV

+1

@ACV nope, я просто живу с ним. Я узнал, что некоторые весенние модули порождают собственные потоки, например. В Cassandra есть пул потоков для соединений или RabbitMQ при использовании контейнеров-слушателей. Это займет некоторое время, чтобы завершить работу после вызова 'context.close()', чтобы остановить приложение. – ESala

+0

См. Мой ответ ниже – ACV

ответ

8

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

+0

Хорошо, я отладил приложение с точкой останова, и есть 17: Тема [Новый рабочий I/O рабочий # (1-17)].Мне нужно разобраться с этим. О ConfigurableApplicationContext.close(), для остановки приложения требуется около 30 секунд, это нормально? – ESala

+0

Придется ждать, пока все работает, чтобы освободить потоки. Звучит как тайм-аут для меня. –

+0

Точно, я подозреваю, что Весна Кассандра почему-то удерживает эти потоки. – ESala

9

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

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

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

+0

ну да .... если вы посмотрите на код на вопрос, я делаю именно это. 'SpringApplication.run (Main.class, args)' возвращает 'ConfigurableApplicationContext', который вы можете сохранить или' @ Autowire' позже, как и я. Проблема, которую я задаю по этому вопросу, заключается в том, что после вызова 'close()' в контексте приложение временно останавливается. – ESala

+0

OK, прозрачный. Может быть, файлы требуют времени для очистки в базе данных – ACV

4

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

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

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

0

Использование 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); 
    } 
} 
1

Это сочетание @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)); 
    } 
} 
Смежные вопросы