Java как закрыть приложение
Размещение сквозной ссылки
Внезапное закрытие Java-приложения: как этого избежать?
Во многих случаях у программистов возникает необходимость выполнить некоторые действия в момент, когда пользователь заканчивает работу с приложением. Но проблема состоит в том, что пользователи не всегда пользуются рекомендованными и правильными способами выхода из приложения. Java предоставляет элегантный подход к выполнению какого-либо кода в середине процесса выгрузки процесса вашего приложения, таким образом гарантируя, что этот код, который, например, занимается какими-либо "очистительными" операциями, будет обязательно выполнен. Эта статья рассказывает о том, каким образом можно вешать обработчик прерывания работы приложения для гарантированного выполнения завершающего кода независимо от того, каким образом пользователь завершил работу с вашим приложением.
Очень часто бывает нужно выполнять какие-то операции по завершению приложения. Например, когда вы пишете текстовый редактор с использованием Swing, и это ваше приложение создает временный файл при начале своей работы. Временный файл должен быть удален, как только пользователь закроет ваше приложение. Если же вы пишете приложение, состоящее из множества сервлетов, встраиваемых в сервлет-контейнер (например, Tomcat или Jetty), то вы должны вызывать метод destroy для каждого из загруженных вами сервлетов до того, как завершится работа приложения.
Во многих случаях вы надеетесь на то, что пользователь закроет приложение приемлемым для вас способом. Например, в первом случае вы можете предоставить ему компонент JButton, после клика на который выполняются необходимые завершающие операции и осуществляется непосредственно выход из приложения. Как альтернативный вариант вы можете повесить обработчик события окна, который бы обрабатывал событие windowClosing. Tomcat же использует специальный batch-файл, который может быть выполнен при правильном завершении работы с приложением. Однако хорошо известно, что пользователи далеко не так часто корректно завершают работу с приложениями. Они могут делать с приложениями все что пожелают. Помимо этого, пользователь может просто-напросто закрыть консоль или завершить свой сеанс работы с операционной системой, оставив при этом ваше приложение незакрытым.
В Java виртуальная машина завершает работу в двух случаях: во-первых, когда из приложения вышли нормальным способом, т.е. был вызван метод System.exit, или же когда остался последний поток, не являющийся демоном. Во-вторых, когда пользователь внезапно прерывает работу виртуальной машины, например, нажимая комбинацию клавиш Ctrl+C или же выходя из системы, не закрыв предварительно работающее Java-приложение.
В качестве следующего примера мы рассмотрим простое Swing-приложение, главный класс которого называется MySwingApp.
Это приложение создает временный файл при запуске. Когда оно закрывается, файл должен быть удален. Код этого приложения приведен в Листинге 2.
Листинг 2
При запуске это приложение вызывает метод initialize. Этот метод, в свою очередь, создает в текущей директории временный файл с именем temp.txt.
Когда пользователь закрывает это приложение, то временный файл должен быть удален. В данном случае нам остается надеяться на то, что пользователь нажмет кнопку Exit, и по ее нажатию будет вызван метод shutdown, который и удаляет временный файл. Однако временный файл не будет удален в случае, если пользователь для выхода из программы воспользуется системной кнопкой X окна приложения или каким-либо другим способом.
В Листинге 3 приведен вариант этого же приложения, который разрешает эту проблему. Новый вариант приложения модифицирует код из Листинга 2, устанавливая shutdown-ловушку. Класс этой ловушки определяется как внутренний класс основного класса приложения. Таким образом, он получает доступ ко всем полям и методам основного класса. В Листинге 3 метод run класса-ловушки просто вызывает метод shutdown основного класса. Этим гарантируется его вызов по завершению приложения.
Я узнал, как закончить (выключить или остановить) мои Java-программы. Я нашел для него два решения.
используя return;
Когда я хочу завершить или прекратить выполнение моей программы, я добавляю это.
используя System.exit(); Иногда я использовал его. Я прочитал о Sytem.exit() из Этот вопрос.
Итак, я знаю немного о них обоих. Но я все еще смущен тем, как они на самом деле работают. Пожалуйста, проверьте коды ниже.
Я уверен, что 2 не появится. Я хотел бы знать, почему return; или другие коды могут писать ниже утверждение System.exit(0); и что было реальным определением для return; (потому что для меня это странно для меня return без каких-либо переменных или значений)?
Вызов System.exit(0) (или любое другое значение в этом случае) приводит к тому, что виртуальная машина Java завершает работу, завершая текущий процесс. Параметр, который вы передадите, будет возвращаемым значением, которое процесс java вернется в операционную систему. Вы можете выполнить этот вызов из любой точки вашей программы - и результат всегда будет таким же - JVM завершается. Поскольку это просто вызов статического метода в классе System , компилятор не знает, что он будет делать - и, следовательно, не жалуется на недостижимый код.
return просто отменяет выполнение текущего метода. Это буквально означает возврат элемента управления вызывающему методу. Если метод объявлен как void (как в вашем примере), вам не нужно указывать значение, так как вам нужно вернуть void . Если метод объявлен для возврата определенного типа, тогда вы должны указать возвращаемое значение - и это значение должно быть указанного типа.
return приведет к выходу программы только в том случае, если она находится внутри метода main основного класса. Если вы попытаетесь поместить код после него, компилятор будет жаловаться на недостижимый код, например:
не будет компилироваться с большинством компиляторов, создавая ошибку unreachable code , указывающую на второй вызов System.out.println .
Потому что System.exit() - это еще один метод для компилятора. Он не читает заранее и не выясняет, что вся программа завершится в этот момент (JVM завершает работу). Ваша ОС или оболочка могут читать целое число, которое передается обратно в методе System.exit() . Стандартно для 0 означает "завершение программы, и все прошло нормально" и любое другое значение для уведомления об ошибке. Разработчик должен документировать эти возвращаемые значения для любых пользователей.
return С другой стороны, это зарезервированное ключевое слово, которое компилятор хорошо знает. return возвращает значение и завершает текущий запуск функции, перемещая резервную копию стека к функции, которая его вызывала (если таковая имеется). В приведенном выше коде возвращается void , поскольку вы не предоставили ничего для возврата.
Посмотрите на различные способы завершения работы приложения Spring Boot.
1. Обзор
Управление жизненным циклом приложения Spring Boot очень важно для готовой к работе системы. Контейнер Spring обрабатывает создание, инициализацию и уничтожение всех компонентов с помощью ApplicationContext.
Акцент в этой записи делается на фазе разрушения жизненного цикла. Более конкретно, мы рассмотрим различные способы завершения работы приложения Spring Boot.
Чтобы узнать больше о том, как настроить проект с помощью Spring Boot, ознакомьтесь со статьей Spring Boot Starter или просмотрите конфигурацию Spring Boot .
2. Конечная точка завершения работы
По умолчанию в приложении Spring Boot включены все конечные точки, кроме /shutdown ; это, естественно, часть конечных точек Привода .
Вот зависимость Maven для их настройки:
И, если мы хотим также настроить поддержку безопасности, нам нужно:
Наконец, мы включаем конечную точку завершения работы в файле application.properties :
Обратите внимание, что мы также должны предоставить любые конечные точки привода, которые мы хотим использовать. В приведенном выше примере мы раскрыли все конечные точки привода, которые будут включать конечную точку /shutdown .
Чтобы закрыть приложение Spring Boot, мы просто вызываем метод POST, подобный этому :
В этом вызове порт представляет порт привода.
3. Закройте контекст приложения
Мы также можем вызвать метод close() непосредственно из контекста приложения.
Давайте начнем с примера создания контекста и его закрытия:
Это уничтожает все бобы, освобождает замки, а затем закрывает фабрику бобов . Для проверки завершения работы приложения мы используем стандартный обратный вызов жизненного цикла Spring с аннотацией @PreDestroy :
Мы также должны добавить боб этого типа:
Вот результат после выполнения этого примера:
Здесь важно иметь в виду: при закрытии контекста приложения родительский контекст не затрагивается из-за отдельных жизненных циклов .
3.1. Закройте текущий контекст приложения
В приведенном выше примере мы создали контекст дочернего приложения, а затем использовали метод close () , чтобы уничтожить его.
Если мы хотим закрыть текущий контекст, одним из решений является простой вызов конечной точки привода /shutdown .
Однако мы также можем создать вашу собственную конечную точку:
Здесь мы добавили контроллер, который реализует интерфейс ApplicationContextAware и переопределяет метод setter для получения текущего контекста приложения. Затем в методе сопоставления мы просто вызываем метод close () .
Затем мы можем вызвать нашу новую конечную точку, чтобы закрыть текущий контекст:
Конечно, если вы добавите такую конечную точку в реальное приложение, вам также захочется защитить ее.
4. Выйдите из приложения Пружины
Spring Application регистрирует shutdown hook в JVM, чтобы убедиться, что приложение завершает работу надлежащим образом.
Бобы могут реализовать Генератор кода выхода интерфейс для возврата определенного кода ошибки:
Тот же код с применением Java 8 lambdas:
После вызова System.exit(ExitCode) программа завершается с кодом возврата 0 :
5. Убейте процесс приложения
Наконец, мы также можем закрыть приложение Spring Boot из-за пределов приложения с помощью скрипта bash. Наш первый шаг для этой опции состоит в том, чтобы контекст приложения записал его PID в файл:
Затем создайте файл shutdown.bat со следующим содержимым:
Выполнение shutdown.bat извлекает идентификатор процесса из файла shutdown.pid и использует команду kill для завершения загрузочного приложения.
6. Заключение
В этой быстрой записи мы рассмотрели несколько простых методов, которые можно использовать для завершения работы запущенного приложения Spring Boot.
Хотя выбор подходящего метода зависит от разработчика; все эти методы должны использоваться по замыслу и по назначению.
Например, .exit() предпочтительнее, когда нам нужно передать код ошибки в другую среду, скажем, JVM для дальнейших действий. Использование Приложения PID дает большую гибкость, так как мы также можем запустить или перезапустить приложение с помощью скрипта bash.
Как правильно завершить работу приложения Swing из кода и каковы подводные камни?
Я пытался закрыть свое приложение автоматически после срабатывания таймера. Но просто вызов dispose() на JFrame не сделал трюка - окно исчезло,но приложение не завершилось. Однако при закрытии окна с помощью кнопки закрыть приложение действительно завершается. Что же мне делать?
как я могу закрыть или свернуть свое приложение из кода, например, когда нажимаю кнопку Домой?
Я сделал приложение java swing, но теперь мне нужна некоторая функциональность для резервного копирования данных из моего приложения. Итак,у меня есть экран, который получает резервные данные, данные расписания резервного копирования и время расписания. Поэтому я хочу, чтобы в определенную дату и.
Ваше действие закрытия по умолчанию JFrame может быть установлено на " DISPOSE_ON_CLOSE " вместо EXIT_ON_CLOSE (почему люди продолжают использовать EXIT_ON_CLOSE, выше моего понимания).
Если у вас есть какие-либо нерасположенные windows или не-демонические потоки, ваше приложение не завершится. Это следует считать ошибкой (и решать ее с помощью System.exit-очень плохая идея).
Наиболее распространенными виновниками являются java.util.Timer и созданный вами пользовательский поток. Оба должны быть установлены в демон или должны быть явно убиты.
Если вы хотите проверить все активные кадры, вы можете использовать Frame.getFrames() . Если все Windows / фреймы удалены, то используйте отладчик для проверки всех не-демонических потоков, которые все еще работают.
before System.exit(0) лучше, так как вы можете написать прослушиватель окна , чтобы выполнить некоторые операции очистки, прежде чем фактически покинуть приложение.
Этот прослушиватель окна позволяет вам определить:
Грубо, но эффективно.
Я делаю приложение java swing с некоторыми потоками. Когда я нажал кнопку 'x' в окне, все запущенные потоки остановились и приложение закрылось должным образом. Но я хочу закрыть приложение из кода java. Я использовал this.dispose(); для закрытия приложения. Но когда я использовал этот метод, окно.
У меня есть приложение java swing, приложение содержит меню swing, мне нужно протестировать это приложение java swing с использованием кода TCL, например, ожидать, что пакет связывается с другим процессом, таким как telnet, ssh аналогичным образом связь возможна с процессом приложения java swing с.
Может быть, безопасный способ-это что-то вроде:
Следующая программа включает в себя код, который завершит программу, не имеющую посторонних потоков, без явного вызова System.exit(). Чтобы применить этот пример к приложениям, использующим threads/listeners/timers/etc, нужно только вставить код очистки, запрашивающий (и, если применимо, ожидающий) их завершения, прежде чем WindowEvent будет вручную инициирован в actionPerformed().
Для тех, кто хочет скопировать/вставить код, способный работать точно так, как показано на рисунке, в конце включен слегка уродливый, но в остальном неуместный основной метод.
Если я правильно вас понял, вы хотите закрыть приложение, даже если пользователь не нажал на кнопку закрытия. Вам нужно будет зарегистрировать WindowEvents, возможно, с addWindowListener() или enableEvents(), в зависимости от того, что больше соответствует вашим потребностям.
Затем вы можете вызвать событие с помощью вызова processWindowEvent(). Вот пример кода, который создаст JFrame, подождет 5 секунд и закроет JFrame без взаимодействия с пользователем.
Как вы можете видеть, метод processWindowEvent() вызывает запуск события WindowClosed, когда у вас есть возможность выполнить некоторую очистку кода, если вам это потребуется, перед закрытием приложения.
Взгляните на документацию Oracle .
Начиная с JDK 1.4 приложение завершается, если:
- Нет никаких отображаемых компонентов AWT или Swing.
- В очереди собственных событий нет собственных событий.
- В java EventQueues нет AWT событий.
В документе говорится,что некоторые пакеты создают отображаемые компоненты, не выпуская их. Программа, вызывающая Toolkit.getDefaultToolkit(), не завершится. это среди прочих приведено в качестве примера.
Кроме того, другие процессы могут поддерживать AWT в живых, когда они по какой-либо причине отправляют события в собственную очередь событий.
Кроме того, я заметил, что в некоторых системах требуется несколько секунд, прежде чем приложение действительно завершится.
Я думаю, идея здесь в том, что WindowListener - вы можете добавить туда любой код, который вы хотели бы запустить до того, как эта штука выключится
В ответ на другие комментарии DISPOSE_ON_CLOSE, похоже, не выходит должным образом из приложения - он только уничтожает окно, но приложение будет продолжать работать. Если вы хотите завершить работу приложения, используйте EXIT_ON_CLOSE.
Похожие вопросы:
Как закрыть приложение java из кода?
Всем привет: У меня есть приложение Java Swing. Есть кнопка разрешить пользователю создать открытое новое окно приложения. Я использую System.Exit(0), когда пользователь решает закрыть приложение.
Я разрабатываю приложение в java Swing (рабочий стол), которое связывается с устройством через последовательный port.the проблема заключается в том, что оно зависает, когда связь теряется с.
как я могу закрыть или свернуть свое приложение из кода, например, когда нажимаю кнопку Домой?
Я сделал приложение java swing, но теперь мне нужна некоторая функциональность для резервного копирования данных из моего приложения. Итак,у меня есть экран, который получает резервные данные.
Я делаю приложение java swing с некоторыми потоками. Когда я нажал кнопку 'x' в окне, все запущенные потоки остановились и приложение закрылось должным образом. Но я хочу закрыть приложение из кода.
У меня есть приложение java swing, приложение содержит меню swing, мне нужно протестировать это приложение java swing с использованием кода TCL, например, ожидать, что пакет связывается с другим.
В Java Swing есть ли способ найти и закрыть все JDialog объектов, отображаемых в данный момент? У меня есть большое приложение, и есть несколько частей, которые могут вызвать для отображения.
Я создаю приложение java swing, когда позволяет использовать несколько команд для командной строки. Я уже добавил эту строку кода, чтобы обеспечить выход моего приложения swing при закрытии.
Читайте также: