Синглтон на сервере приложений Java. Насколько плоха идея?

В настоящее время я работаю над старым Java-кодом, который был разработан без использования серверов приложений. Это в основном куча "кода черного ящика" с интерфейсом ввода и выходным интерфейсом. Все в классах "черного ящика" являются статическими структурами данных, которые содержат состояние, которое помещается через алгоритмы с временными интервалами (каждые 10 секунд). Черный ящик запускается из основного метода.

Чтобы это было легко для меня, я думаю о том, чтобы сделать "черный ящик" Синглтон. В принципе, любой, кто хочет получить доступ к логике внутри черного ящика, получит тот же экземпляр. Это позволит мне использовать Message Driven beans как входной сигнал в черный ящик, а JMS Publisher - как выход черного ящика.

Насколько плоха идея? Любые советы?

Одна из основных проблем, которые у меня есть, - это могут быть потоки в коде "черного ящика", о котором я не знаю.

Есть ли такая вещь, как "объекты с областью приложения" в EJB?

Примечание. Я использую Glassfish

Ответ 1

Если вы используете простой синглтон, , вы столкнетесь с проблемами после входа в кластерную среду.

В таком сценарии у вас есть несколько загрузчиков классов на нескольких JVM, и ваш шаблон sinlgeton будет ломаться, поскольку у вас будет несколько экземпляров этого класса.

Единственное допустимое использование одноэлемента на сервере приложений (возможно, в кластерной среде) - это когда вы используете singleton полностью без учета состояния и используется только в качестве удобства для доступа к глобальным данным/функциям.

Я предлагаю проверить решение поставщика вашего сервера приложений для этой проблемы. Большинство, если не все поставщики, предлагают некоторое решение для требований вашего типа.

В частности, для Glassfish, который, как вы говорите, вы используете, проверьте Поддержка Singleton EJB для Glassfish. Это может быть так же просто, как добавить отдельную аннотацию.

Ответ 2

Я бы сказал, что создание синглтона на самом деле является единственной жизнеспособной идеей. Предполагая, что код внутри этого "черного ящика", как известно, использует статические поля, абсолютно небезопасно создавать два экземпляра этого фасада. Результаты непредсказуемы в противном случае.

Ответ 3

Отнюдь не плохая идея, это на самом деле звучит для меня как потенциально неплохая идея.

Просто с точки зрения дизайна программы: если ваш черный ящик концептуально является "объектом" со свойствами и методами, которые работают на них, затем превращайте его в объект, даже если он будет только когда-либо одним из них.

Ответ 4

Он должен работать, но есть некоторые проблемы, с которыми вам придется иметь дело.

Threading, как вы уже упоминали. MDB запускается в контейнере EJB, где вы не можете создавать свои собственные потоки, поэтому у вас есть потенциальная проблема. Если у вас есть доступ к фактическому коду (который, как вам кажется, вам нравится), вы можете захотеть сделать рефакторинг, чтобы либо устранить потоки, либо использовать "одобренный" метод потоковой передачи. CommonJ TimerManager, вероятно, будет работать в вашем заявленном случае, так как он выполняет некоторую задачу с интервалом. Существуют версии, доступные для большинства серверов приложений (включая WAS и Weblogic).

Загрузка классов - это зависит от вашей конфигурации. Если singleton создается и управляется из MDB в пределах одного EAR, вы будете в порядке. Отдельный EAR будет означать разные загрузчики классов и несколько экземпляров вами Singleton. Не могу прокомментировать, будет ли это проблемой в вашем случае или нет без дополнительной информации.

Ответ 5

Мне не хватает точки? Вы упомянули, что "код черного ящика" содержит состояние. MDB могут быть ограничены одним экземпляром для каждого адресата, но без надлежащей настройки вы получите несколько MDB. Все они работают с вашим единственным экземпляром "кода черного ящика". Для меня это выглядит не очень хорошо, потому что один bean переопределит состояние "черного кода", другой bean создал несколько тиков раньше.

Ответ 6

Мне кажется, что артефакт, который лучше подходит вашему требованию, - это JBoss MBean. (Если вы думаете о JBoss как кандидате AS).

Стандартный пример MBean

MBeans также могут быть развернуты как Singletons, в случае кластеризации JBoss.

Кластеризация с помощью JBoss

Я надеюсь, что это будет полезно для вас.

Рафа.

Ответ 7

Исправьте код, чтобы как можно скорее избавиться от статики. Синглтоны - это не шаг в правильном направлении - они просто добавляют лишнее неправильное направление.

Ответ 8

Не используйте синглтоны, где состояние может измениться.

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

Ответ 9

В мире веб-сервера объект может быть привязан к запросу, сеансу или приложению. Возможно, вам нужен объект области приложения.

Поиск документов для "объекта области приложения" или "объекта жизненного цикла приложения".

Ответ 10

Почему бы не создать интерфейс отдыха для пустого поля и позволить клиентам делать http-вызовы?

Ответ 11

IMO, неплохо иметь контейнер EJB для ваших потребностей Singleton. В Java EE 6 размещение аннотации @Singleton в вашей сессии bean дает вам именованный синглтон.