Соответствует ли текущая реализация клиента вашим требованиям?Если это так, я бы не стал его менять.Если текущая реализация клиента не удовлетворяет вашим требованиям, я бы изменил ее.Изменение программного обеспечения, которое работает без проблем и отвечает вашим потребностям (и без явных проблем), просто для того, чтобы придерживаться «наилучшей практики», почти наверняка не лучшая инвестиция ресурсов.
В конечном итоге поведениеПриложение зависит от самого приложения.Я не понимаю, как запуск приложения в качестве службы или выполнение каких-либо других действий, не связанных с приложением, фактически вынуждает его работать и работать должным образом, пока он слушает / ждет сообщений.Было бы ошибкой, если бы приложение было запрограммировано, например, использовать API-интерфейс JMS и создать MessageListener (то есть класс, отвечающий за асинхронный прием сообщений), а затем завершить работу, фактически не ожидая сообщений.Запуск такого приложения в качестве службы, чтобы ОС продолжала перезапускать его после неправильного выхода, не будет хорошим решением.
Лучше всего иметь правильно написанный клиент.Поддерживать его с помощью какого-либо внешнего механизма - плохая практика.
Предоставленный вами пример кода плохо написан и имеет некоторые явные проблемы:
- Падение объектов
Connection
и Session
вне области, что означает, что они никогда не могут быть должным образом закрыты.В конечном итоге эти объекты будут собраны мусором JVM.Это неправильное управление ресурсами. - Единственная причина, по которой приложение не завершает работу полностью, связана с тем, как реализован клиент ActiveMQ 5.x (т. Е. Открытое соединение блокирует завершение процесса JVM).Эта деталь реализации не является частью публичного договора, предоставляемого JMS API, и поэтому на нее не следует полагаться.Если бы вы использовали другую реализацию клиента JMS, например, клиент JMS ядра ActiveMQ Artemis, приложение будет полностью завершаться, как только выйдет
main()
.
Чтобы исправить это, ваш метод main()
должен ждать после создания экземпляра JmsTestWithoutClose
.Есть много способов сделать это в Java:
- Используйте цикл
while
с Thread.sleep()
, где условие цикла может быть изменено по мере необходимости, чтобы позволить приложению выйти. - Используйте объект, специально разработанный для координации потоков, такой как
java.util.concurrent.CountDownLatch
.При использовании CountDownLatch
метод main()
может вызывать await()
, а когда приложение завершает обработку сообщений, например, реализация MessageListener
может вызывать countDown()
- Использование циклического чтения
while
ввод с консоли и продолжается только при вводе специальной строки (например, exit ).
В любом случае важно, чтобы приложение закрыло все созданные им ресурсы (например, сеансы, соединения и т. д.).