Какой scope у Spring-бина по умолчанию?
- Какие бывают scope бинов?
По умолчанию singleton — один экземпляр на контейнер, общий для всех потоков. Ещё: prototype (новый на каждый запрос к контейнеру), веб-scope request, session, application, websocket.
- Singleton должен быть потокобезопасным — без изменяемого состояния
- Prototype в singleton внедряется один раз — нужен ObjectProvider или lookup
- Для prototype контейнер не вызывает @PreDestroy
А ещё Singleton Spring — один на контекст, а не на JVM, как паттерн Singleton
Подробно
singleton (по умолчанию) — контейнер создаёт один экземпляр при старте (или при первом обращении, если @Lazy) и отдаёт его всем. Все запросы обслуживаются одним объектом в разных потоках — поэтому сервисы должны быть без изменяемого состояния: поле currentUser в контроллере — гонка между запросами.
prototype — каждый getBean() или внедрение создаёт новый объект. Контейнер не управляет его уничтожением.
Веб-scope (в веб-контексте):
- request — на HTTP-запрос;
- session — на HTTP-сессию;
- application — на ServletContext;
- websocket — на WebSocket-сессию.
Такие бины внедряются в singleton через scoped proxy: в singleton лежит прокси, который при каждом вызове находит экземпляр текущего запроса.
Ловушка prototype в singleton: singleton создаётся один раз, и prototype-зависимость внедрится тоже один раз. Для нового экземпляра при каждом использовании — ObjectProvider<T>.getObject(), @Lookup-метод или scoped proxy.
Что хотят услышать
- Singleton по умолчанию и его требования к потокобезопасности.
- Prototype и веб-scope.
- Проблема prototype внутри singleton.
Частые ошибки
- Хранить состояние запроса в поле singleton-бина.
- Ожидать новый prototype при каждом вызове метода singleton.
Проверьте себя
Один верный вариант. Подумайте, потом откройте ответ.
Показать варианты и ответ
- ✗prototype
- ✗application
- ✓singleton
- ✗request
Что спросят дальше
- Чем prototype отличается от singleton?
- Как singleton-бин держит prototype-зависимость?
Разбор темы
- Бины: жизненный цикл и scopes
Бин и BeanDefinition, полный жизненный цикл, роль BeanPostProcessor, области видимости и их ловушки.
Связанные вопросы
- Как корректно получать prototype-бин внутри singleton-бина, чтобы каждый раз создавался новый экземпляр? Senior
- Сколько экземпляров бина со scope singleton создаст контейнер? Junior
- Разработчик добавил в @RestController поле private User currentUser и заполняет его в начале каждого метода. Что не так? Middle
Разбор собеседования с sotto
После собеседования sotto разбирает разговор: оценка, каждый вопрос — хорошо, частично или слабо, чего не хватило в ответе и над чем поработать к следующему разу. Первые 30 минут бесплатно.