Ответ
В Spring-приложении существует несколько типов контекстов (scope), каждый со своей областью видимости и временем жизни.
Основные контексты (scopes) бинов Spring:
singleton(по умолчанию): Один экземпляр бина на весьApplicationContext. Используется для stateless-сервисов.prototype: Новый экземпляр бина при каждом запросе через контейнер.request: Один экземпляр на жизненный цикл одного HTTP-запроса. Доступен только в веб-приложениях.session: Один экземпляр на HTTP-сессию пользователя.application: Один экземпляр наServletContext. Аналогиченsingleton, но привязан к контексту веб-приложения.
Пример объявления бина с областью видимости request:
@Component
@Scope(value = WebApplicationContext.SCOPE_REQUEST, proxyMode = ScopedProxyMode.TARGET_CLASS)
public class RequestScopedBean {
private final String data = "Request-specific data";
// ...
}
Важные связанные понятия:
ApplicationContext: Корневой контейнер Spring, обычно один на приложение, но могут быть иерархии (родительский/дочерний).WebApplicationContext: Специализированный контекст для веб-приложений.SecurityContext(Spring Security): Хранит информацию об аутентификации и правах текущего потока (привязан кThreadLocal).
Выбор контекста определяет, как и когда создаются/уничтожаются бины, что критично для управления состоянием и ресурсами.
Ответ 18+ 🔞
А, ну вот, опять эти ваши контексты, блядь! Сидишь такой, думаешь — ну что тут сложного, ан нет, ёпта! Spring тут развел целый театр с областями видимости, просто ёперный театр!
Смотри, в общем, есть у них там несколько «контекстов», или, по-ихнему, scope. Это такая штука, которая решает, сколько раз твой бин родится и как долго будет мучить этот мир.
Основные-то вот эти, на которые все молятся:
singleton(он же по умолчанию, ленивая жопа): Один чувак на весь бардак, на весьApplicationContext. Поставили его в угол — и он там стоит, как пень, всех обслуживает. Идеально для всяких безликих сервисов, которые нихуя о тебе не помнят.prototype: А это уже похуист. Каждый раз, как ты его просишь, он такой: «О, новый клиент!» — и лепит тебе свежую копию. Как одноразовые стаканчики, блядь.request: Это уже для веб-дегенератов. Один экземпляр живёт ровно столько, сколько длится один HTTP-запрос. Пришёл запрос — родился, отдал ответ — в утиль. Красиво, чо.session: А этот уже хитрее, подлиза. Запомнит тебя на всю сессию. Зашёл в приложение — он с тобой, вышел — он, сука, помер. Как временная татуха, блядь.application: Почти какsingleton, но привязан не к всему Spring, а конкретно к веб-среде, кServletContext. Ну, чтобы совсем не запутаться, видимо.
Вот смотри, как этого request урода объявить, чтоб он работал:
@Component
@Scope(value = WebApplicationContext.SCOPE_REQUEST, proxyMode = ScopedProxyMode.TARGET_CLASS)
public class RequestScopedBean {
private final String data = "Request-specific data";
// ...
}
Видишь эту proxyMode? Это чтобы Spring, хитрая жопа, подсунул тебе прокси, а не реальный бин, пока запрос не начался. А то будет тебе null вместо данных, и волнение ебать!
И ещё, бля, куча умных слов вокруг плавает:
ApplicationContext: Это главный начальник, корневой контейнер. Обычно он один, но бывают и семейные разборки — родительский и дочерние. Драма, короче.WebApplicationContext: Тот же начальник, но в камуфляже и с стволом, потому что работает в вебе.SecurityContext(из банды Spring Security): Вообще отдельная история. Этот чувак вThreadLocalсидит и помнит, кто ты такой и на что имеешь право. Типа твой цифровой паспорт в рамках потока.
Короче, выбор контекста — это, блядь, фундаментально! От этого зависит, кто, когда и как будет создаваться и подыхать. Не угадаешь — получишь утечку памяти или состояние, которое на всех расползётся, как дерьмо по вентилятору. Думай, бошка, думай!