Я разрабатываю приложение, которое по сути представляет собой службу, которая будет запускаться из командной строки. У меня есть опция в файле config
для отображения GUI
. Если пользователь хочет, чтобы он отображал окно, я могу вызвать свой метод shutdown()
, используя событие WindowClosing
из Swing или кнопку выключения. Однако, если пользователь выбирает вариант без GUI, я не уверен, как обеспечить вызов этого метода при нажатии Control-C в командной строке. Мой метод shutdown()
обновляет некоторые важные данные в базе данных и останавливает потоки, поэтому мне нужно, чтобы он запустился. Я провел небольшое исследование и попробовал что-то вроде этого:
public static void main(String args[])
{
//Look and Feel Initialization
try
{
for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels())
{
if ("Nimbus".equals(info.getName()))
{
javax.swing.UIManager.setLookAndFeel(info.getClassName());
break;
}
}
}
catch (ClassNotFoundException | IllegalAccessException | InstantiationException | UnsupportedLookAndFeelException ex)
{
logger.error("Error initializing look and feel : " + ex.getMessage());
}
//Application Initialization
SpringApplication application = new SpringApplication(MDHIS_Service.class);
application.addListeners((ApplicationListener<ContextClosedEvent>) (ContextClosedEvent e) ->
{
shutdown();
});
application.run(args);
}
Проблема в том, что мой метод shutdown()
далек от статики. Я не знаю, как подключить это к контексту Spring Boot, чтобы он запускал этот метод перед остановкой. Я попробовал аннотацию @PreDestroy
, но метод не запустился должным образом.
Любая помощь будет оценена по достоинству.
Спасибо!
См. Runtime API, чтобы зарегистрировать ловушку выключения - в основном используйте поток для вызова метода, когда JVM завершается (обычно или через прерывание, такое как CTRL + C).
В этом случае похоже, что shutdown()
будет статическим методом внутри класса, который определяет main()
, поэтому что-то вроде этого:
public static void main(String args[]) {
...
if (using command line) {
Runtime.getRuntime().addShutdownHook(new Thread( () -> shutdown() ));
}
}
Что касается использования @PreDestroy, этот аналогичный вопрос также может помочь.
Это моя проблема, метод выключения делает много вещей и не может быть вызван статически. К сожалению, ни один из этих методов не позволяет этого сделать.
После некоторых дополнительных исследований я закончил реализацию интерфейса SmartLifecycle. Мой метод getPhase()
возвращает Integer.MAX_VALUE;
, что означает, что сначала уничтожается компонент. Затем метод stop можно использовать для вызова кода очистки и проверки того, что все bean-компоненты ведения журнала / доступа к БД все еще живы.
Возможный дубликат Метод @PreDestroy одноэлементного компонента Spring не вызывается