Spring Boot - Как зарегистрировать перехватчик выключения для приложения без графического интерфейса пользователя

Я разрабатываю приложение, которое по сути представляет собой службу, которая будет запускаться из командной строки. У меня есть опция в файле 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, но метод не запустился должным образом.

Любая помощь будет оценена по достоинству.

Спасибо!

Возможный дубликат Метод @PreDestroy одноэлементного компонента Spring не вызывается

Hans Westerbeek 18.10.2018 18:30
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
0
1
1 587
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

См. Runtime API, чтобы зарегистрировать ловушку выключения - в основном используйте поток для вызова метода, когда JVM завершается (обычно или через прерывание, такое как CTRL + C).

В этом случае похоже, что shutdown() будет статическим методом внутри класса, который определяет main(), поэтому что-то вроде этого:

public static void main(String args[]) {
    ...
    if (using command line) {
        Runtime.getRuntime().addShutdownHook(new Thread( () -> shutdown() ));
    }
}

Что касается использования @PreDestroy, этот аналогичный вопрос также может помочь.

Это моя проблема, метод выключения делает много вещей и не может быть вызван статически. К сожалению, ни один из этих методов не позволяет этого сделать.

Martin 18.10.2018 20:15
Ответ принят как подходящий

После некоторых дополнительных исследований я закончил реализацию интерфейса SmartLifecycle. Мой метод getPhase() возвращает Integer.MAX_VALUE;, что означает, что сначала уничтожается компонент. Затем метод stop можно использовать для вызова кода очистки и проверки того, что все bean-компоненты ведения журнала / доступа к БД все еще живы.

Другие вопросы по теме