Как одиночные элементы обрабатываются в веб-приложении?

Из того, что я понимаю, одиночный элемент в основном, когда у Вас есть член парламента, не занимающий официального поста, который представляет объект, для которого Вы хотите иметь единственный экземпляр. Тогда в конструкторе Вы инициализируете членский объект.

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

Теперь в веб-приложении, как это работает? Единственный экземпляр просто бродит вокруг в контейнере (скажите, что кот), пока кот не является завершением работы?

15
задан skaffman 6 March 2010 в 10:29
поделиться

4 ответа

Да, есть одноэлементный шаблон, который работает так, как вы описываете. Это проблематично и сопровождается оговорками, о которых говорил Стивен С. выше. Если вам нужны данные одного экземпляра, лучшим вариантом будет создание их с помощью контейнера Spring (или других контейнеров, поддерживающих это), который будет обрабатывать создание экземпляра (что гораздо более проблематично, чем вы думаете).

Если вам необходимо развернуть свой собственный, прочтите полностью об идиоме блокировки с двойной проверкой и связанных с ней проблемах, чтобы понять проблемы, которые могут возникнуть при создании экземпляров синглтон. Если ваш экземпляр нетривиален, на самом деле очень легко получить несколько экземпляров или условий гонки в экземпляре. Я сам это сделал. В производстве (но это было давно;))

0
ответ дан 1 December 2019 в 04:53
поделиться

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

Вы можете найти некоторую информацию о загрузчиках классов Tomcat в документации.

6
ответ дан 1 December 2019 в 04:53
поделиться

Следует проводить различие между шаблоном Singleton и его реализацией. Большинство, если не все распространенные реализации Singleton страдают от упомянутых проблем с загрузкой классов, а также с сериализацией, безопасностью потоков и т. Д. См. https://www.securecoding.cert.org/confluence/display/java/MSC07-J.+ Предотвращение + множественных + экземпляров + одноэлементных + объектов для достаточно тщательного обзора.

Однако шаблон синглтона в самом широком смысле может быть любой службой, которая гарантированно уникальна в определенном контексте. Уникальность синглтона может быть указана только относительно заданной области, такой как загрузчик классов, JVM, контейнер или кластер; уровень уникальности зависит от реализации, которую следует выбирать исходя из требований приложения.

Два очень распространенных требования, ведущих к использованию синглтонов, - это внедрение зависимостей (c.q. с использованием фабрики) и кэширование в памяти. В обоих случаях есть хорошие фреймворки, которые скрывают аспект синглтона от клиента и предлагают достаточный уровень уникальности, например, в контейнере корпоративного приложения. Для внедрения зависимостей на ум приходят Spring, Guice или Pico. Я знаю, что Ehcache является ведущим решением для кеширования, но, безусловно, есть и другие решения. (забавные мелочи: название «ehcache» - это палиндром)

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

Боязнь синглтонов, на мой взгляд, проистекает из множества плохих реализаций, которые возможны и распространены. И даже если реализация Singleton сама по себе «безопасна», ее вызов напрямую (через статический доступ) во всем приложении приводит к сильной связи и плохой тестируемости.

Улучшение, которое вы можете сделать, если у вас есть фабрика Singleton в вашем приложении, - это рефакторинг ее клиентов, чтобы они не вызывали фабрику всякий раз, когда им нужна зависимость, а предоставляли частное поле и общедоступный установщик, разрешающий зависимость быть введенным. Затем вы можете централизовать инициализацию клиентов, возможно, на той же фабрике, и оставить код клиента чистым, слабо связанным и тестируемым (теперь вы можете внедрить фиктивные зависимости). Это также может быть первым шагом на пути к внедрению инфраструктуры внедрения зависимостей, такой как Spring.

Надеюсь, что где-то в этом довольно длинном и бессвязном посте я помог ответить на ваш вопрос! (-;

5
ответ дан 1 December 2019 в 04:53
поделиться

Как это работает в веб-приложении? Остается ли один экземпляр в контейнере (скажем, tomcat) до тех пор, пока tomcat не будет выключен?

Ответ @Greg объясняет, что могут быть разные экземпляры класса singleton (фактически разные классы с точки зрения JVM), если каждый контейнер webapp в TomCat есть собственный загрузчик классов.

В любом случае время жизни (GC) синглтона будет временем жизни соответствующих загрузчиков классов. Однако на практике ссылки на загрузчик классов могут легко просочиться, в результате чего синглтон будет жить до выхода из JVM.

Это одна из причин того, что обычные синглтоны проблематичны в веб-приложениях. Лучше использовать экземпляры с ограниченным объемом контейнера; например как поддерживается Spring и другими фреймворками IoC.

0
ответ дан 1 December 2019 в 04:53
поделиться
Другие вопросы по тегам:

Похожие вопросы: