В чем разница между scope Singleton и Prototype в Spring?

Ответ

Singleton и Prototype — это основные области видимости (scope) бинов в Spring, определяющие жизненный цикл экземпляра.

Singleton (по умолчанию)

  • Контейнер создает только один экземпляр бина.
  • Все запросы (инъекции, вызовы getBean()) получают один и тот же объект.
  • Используется для stateless-компонентов: сервисы, репозитории, утилитные классы.
  • Потокобезопасность: Бин не должен хранить изменяемое состояние, иначе возможны состояния гонки (race condition).

Prototype

  • Контейнер создает новый экземпляр при каждом запросе.
  • Каждая инъекция или вызов getBean() возвращает новый объект.
  • Используется для stateful-компонентов: объекты с состоянием, специфичным для запроса (например, DTO, данные сессии пользователя).
  • Управление памятью: Контейнер Spring не управляет полным жизненным циклом prototype-бина после его создания и передачи клиенту. Уничтожение — ответственность клиентского кода.

Пример объявления

// Singleton (явное указание избыточно, так как это scope по умолчанию)
@Component
@Scope("singleton") // или @Scope(ConfigurableBeanFactory.SCOPE_SINGLETON)
public class OrderService { ... }

// Prototype
@Component
@Scope("prototype") // или @Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
public class ShoppingCart { ... }

Ключевой вывод: Выбор зависит от необходимости разделять состояние. Singleton — для общей логики, Prototype — для изолированных данных.

Ответ 18+ 🔞

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

Singleton — это, блядь, дефолтная штука. Контейнер создаёт один-единственный экземпляр на всю свою гребаную жизнь. Все, кто его просит — через инъекцию или getBean() — получают один и тот же объект. Представь, как будто у тебя одна бутылка водки на всю компанию — все пьют из неё, и если кто-то мудак туда пепел насыпет, то всем достанется. Поэтому его используют для stateless-компонентов: сервисов, репозиториев, утилит. Потокобезопасность, ёпта, на тебе! Не храни в нём изменяемое состояние, а то будет race condition, и все полетят в пизду.

Prototype — это уже другая история, блядь. Здесь контейнер каждый раз, когда его просят, создаёт новый, свеженький экземпляр. Каждый запрос — новый объект. Это как если бы каждому гостю наливали из новой, запечатанной бутылки. Используется для stateful-компонентов, где у каждого своё состояние: корзина покупок, DTO, данные сессии. Но запомни раз и навсегда: контейнер, создав этот бин, смывает руки. Он не управляет его жизненным циклом до конца. Уничтожить его — твоя головная боль, клиент.

Как это объявить, чтобы не облажаться

// Singleton (можно и не писать, и так сработает, но для ясности)
@Component
@Scope("singleton") // Конкретнее: @Scope(ConfigurableBeanFactory.SCOPE_SINGLETON)
public class OrderService { ... }

// Prototype
@Component
@Scope("prototype") // Или @Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
public class ShoppingCart { ... }

Итог, ёпта: Всё упирается в состояние. Нужно делиться одним экземпляром на всех — бери Singleton, но будь аккуратен, как сапёр. Нужна изоляция и своя песочница для каждого — твой выбор Prototype, но не забудь потом за собой убрать, а то память проебешь.