Этот вопрос проверяет понимание различий между prototype и singleton бинами в Spring, что важно для управления жизненным циклом объектов и их состоянием в контейнере.
В Spring Framework scope (область видимости) бина определяет, как контейнер управляет его жизненным циклом и созданием экземпляров. Два наиболее часто используемых scope — это singleton и prototype.
Это scope по умолчанию. Когда бин определён как singleton, Spring IoC контейнер создаёт ровно один экземпляр этого бина. Этот единственный экземпляр хранится в кэше, и все последующие запросы и ссылки на этот бин возвращают этот кэшированный объект. Singleton бины идеально подходят для stateless сервисов, таких как утилитные классы, сервисы доступа к данным или компоненты, не хранящие состояние конкретного клиента.
@Component // По умолчанию scope = "singleton"
public class OrderService {
// Stateless методы
public BigDecimal calculateTotal(Order order) { ... }
}Когда бин определён как prototype, Spring IoC контейнер создаёт новый экземпляр бина каждый раз, когда он запрашивается. Это означает, что контейнер не управляет полным жизненным циклом prototype бина: после создания и настройки (injection зависимостей) он передаётся клиенту, и контейнер больше не отслеживает его. Prototype подходит для stateful компонентов, где каждый клиент (например, HTTP-запрос или сессия пользователя) должен работать со своим собственным, изолированным экземпляром.
@Component
@Scope("prototype")
public class ShoppingCart {
private List items = new ArrayList<>();
// Stateful объект, у каждого клиента своя корзина
public void addItem(Item item) { items.add(item); }
}Важно помнить о побочных эффектах при внедрении prototype бина в singleton. Если singleton бин имеет поле с prototype бином, то этот prototype бин будет внедрён только один раз при создании singleton, что фактически превратит его в singleton для этого контекста. Чтобы каждый раз получать новый экземпляр prototype, можно использовать lookup-метод или провайдер (например, ObjectFactory<T> или Provider<T>).
Вывод: Используйте singleton scope для stateless, многократно используемых компонентов, таких как сервисы и репозитории. Выбирайте prototype scope для stateful объектов, жизненный цикл которых короткий или зависит от клиентского контекста, например, корзина покупок в веб-приложении.