Ответ
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, но не забудь потом за собой убрать, а то память проебешь.