Какие типы контекстов существуют в Spring-приложении и какова их область видимости?

Ответ

В Spring-приложении существует несколько типов контекстов (scope), каждый со своей областью видимости и временем жизни.

Основные контексты (scopes) бинов Spring:

  1. singleton (по умолчанию): Один экземпляр бина на весь ApplicationContext. Используется для stateless-сервисов.
  2. prototype: Новый экземпляр бина при каждом запросе через контейнер.
  3. request: Один экземпляр на жизненный цикл одного HTTP-запроса. Доступен только в веб-приложениях.
  4. session: Один экземпляр на HTTP-сессию пользователя.
  5. 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. Это такая штука, которая решает, сколько раз твой бин родится и как долго будет мучить этот мир.

Основные-то вот эти, на которые все молятся:

  1. singleton (он же по умолчанию, ленивая жопа): Один чувак на весь бардак, на весь ApplicationContext. Поставили его в угол — и он там стоит, как пень, всех обслуживает. Идеально для всяких безликих сервисов, которые нихуя о тебе не помнят.
  2. prototype: А это уже похуист. Каждый раз, как ты его просишь, он такой: «О, новый клиент!» — и лепит тебе свежую копию. Как одноразовые стаканчики, блядь.
  3. request: Это уже для веб-дегенератов. Один экземпляр живёт ровно столько, сколько длится один HTTP-запрос. Пришёл запрос — родился, отдал ответ — в утиль. Красиво, чо.
  4. session: А этот уже хитрее, подлиза. Запомнит тебя на всю сессию. Зашёл в приложение — он с тобой, вышел — он, сука, помер. Как временная татуха, блядь.
  5. 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 сидит и помнит, кто ты такой и на что имеешь право. Типа твой цифровой паспорт в рамках потока.

Короче, выбор контекста — это, блядь, фундаментально! От этого зависит, кто, когда и как будет создаваться и подыхать. Не угадаешь — получишь утечку памяти или состояние, которое на всех расползётся, как дерьмо по вентилятору. Думай, бошка, думай!