Почему область прототипа используется с компонентом с сохранением состояния?

#java #spring #inversion-of-control #javabeans

#java #spring #Инверсия контроля #javabeans

Вопрос:

Spring docs — Как эмпирическое правило, вы должны использовать область прототипа для всех компонентов с сохранением состояния, в то время как область singleton должна использоваться для компонентов без состояния.

Таким образом, компонент с сохранением состояния необходим, когда вам нужно последовательно поддерживать некоторое состояние / данные в контексте. Скажем, банковское приложение. Можно было бы ожидать, что ваш объект будет синхронизирован во время различных операций (ввод, вывод средств и т.д.).

Итак, в области singleton вы получаете то же самое — согласованность объектов во всем контексте.

Итак, почему javadoc указывает противоположное?

Помогите !! 🙂

Комментарии:

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

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

Ответ №1:

В основном это связано с проблемами синхронизации, которые необходимо учитывать при использовании одноэлементных компонентов в многопоточной среде. При использовании компонентов прототипа каждый запрос к компоненту будет создавать новый экземпляр компонента, и, таким образом, вам не нужно заботиться о синхронизации доступа к состоянию компонента по потокам. Но вам нужно быть очень осторожным при смешивании компонентов prototype и singleton, поскольку компоненты prototype будут подключены к компоненту singleton только один раз. То есть он фактически становится одноэлементным внутри этого компонента…

Если вам действительно нужно использовать компоненты прототипа в одноэлементных компонентах, вы должны использовать @Lookup к методу.

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

Одним из примеров одноэлементных компонентов, имеющих состояние, являются кэши. С помощью выделенных библиотек кэша, таких как infinispan, guava, hazlecast, … здесь вам не нужно особо заботиться о синхронизации, поскольку этот аспект обрабатывается этими библиотеками за вас.

Учитывая ваш банковский пример, вы, вероятно, не хотите хранить детали транзакции в специальном хранилище, таком как Java heap. Если ваше приложение по какой-либо причине выйдет из строя, вся эта информация будет безвозвратно потеряна. Эта информация должна храниться в постоянном хранилище, таком как база данных.

Комментарии:

1. Это верно, но в случае, если есть компонент A, который является одноэлементным; внутри компонента A находится свойство типа bean B (это prototype); в этом случае, в случае компонента B, на контейнер spring по-прежнему приходится только один экземпляр, поскольку родительский класс является одноэлементным.

2. где вы это нашли: With prototype beans each thread will get a new instance of the bean ? в spring doc написано results in the creation of a new bean instance every time a request for that specific bean is made . При этом я понимаю, что каждый параметр указывается, например, в другом компоненте.

3. @LinuRadu, да thread здесь не лучшая формулировка, это должен быть запрос. Я перефразирую это. В вашем примере выше, если у вас есть третий компонент C со свойством типа B , будет второй экземпляр B .

4. Правильно, что, как вы указали, будет создан еще один экземпляр типа B, но относительно you don’t need to care about synchronizing access to the bean’s state across threads почему вы говорите, что проблема синхронизации решена? Вероятно, в случае, если у вас есть все прототипы tree-beans (как @RestController, так и @Service).

5. Точно. Вывод должен быть «не использовать компоненты прототипа».