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

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

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

насколько это плохая идея? Есть советы?

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

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

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

11 ответов


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

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

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

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

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


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


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

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


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

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

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


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


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

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

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

кластеризация с JBoss

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

Рафа.


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


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

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


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

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


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


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