Короткий ответ
Область видимости (scope) определяет, сколько экземпляров бина создаёт контейнер и как они используются. По умолчанию все бины — singleton: один экземпляр на весь контейнер. Скоуп prototype создаёт новый экземпляр при каждом запросе из контейнера.
Как это работает подробнее
Spring поддерживает шесть скоупов: singleton (один экземпляр на весь контейнер), prototype (новый экземпляр на каждый запрос), request (на каждый HTTP-запрос), session (на каждую HTTP-сессию), application (общий для всего веб-приложения) и websocket (на каждую WebSocket-сессию). Скоупы request, session, application и websocket доступны только в веб-приложениях.
- Singleton: контейнер создаёт один экземпляр и полностью управляет его жизненным циклом, включая вызов метода уничтожения при завершении приложения; экономит память и подходит для stateless-бинов — сервисов и репозиториев.
- Prototype: при каждом запросе создаётся новый объект; после передачи вызывающему коду контейнер больше не управляет им, поэтому метод уничтожения для prototype-бинов не вызывается; подходит для stateful-объектов.
- Задание скоупа: аннотация
@Scopeнад классом или методом@Bean, либо атрибутscopeв XML-конфигурации.
Пример кода
AppConfig.java
@Configuration
public class AppConfig {
@Bean
@Scope("singleton")
public CacheService cacheService() {
return new CacheService();
}
@Bean
@Scope("prototype")
public CartService cartService() {
return new CartService();
}
}Что использовать на практике
- Сервисы и репозитории оставляйте со скоупом по умолчанию
singleton— это экономит память и упрощает управление. - prototype берите для объектов с собственным состоянием, например корзины или временных объектов.
- В веб-приложениях для данных запроса или пользователя используйте
requestиsession.
Подводные камни
- Помните главный нюанс: для prototype-бинов Spring не вызывает метод уничтожения — после создания контейнер отдаёт управление вызывающему коду.
- Веб-скоупы
request,session,applicationиwebsocketработают только в веб-приложениях. - Если singleton-бин зависит от prototype-бина, при каждом обращении «свежий» экземпляр не создаётся — нужен дополнительный приём вроде
ObjectProvider.
Как отвечать на собеседовании
- Назовите шесть скоупов: singleton, prototype, request, session, application, websocket → отметьте, что по умолчанию используется singleton → объясните разницу: singleton создаётся один раз и управляется контейнером, prototype — при каждом запросе и без управления контейнером после передачи → добавьте, что веб-скоупы доступны только в веб-приложениях.