Какие области видимости (scopes) бинов вы знаете в Spring Framework?

Ответ

Spring предоставляет шесть стандартных областей видимости (scopes) для бинов. Их доступность зависит от контекста приложения.

Стандартные scopes:

  1. singleton (по умолчанию) — контейнер создает единственный экземпляр бина, и все запросы возвращают этот же объект.
  2. prototype — контейнер возвращает новый экземпляр при каждом запросе бина (через getBean() или инъекцию).
  3. request — один экземпляр на жизненный цикл одного HTTP-запроса (только для веб-приложений).
  4. session — один экземпляр на HTTP-сессию пользователя (только для веб-приложений).
  5. application — один экземпляр на жизненный цикл ServletContext (только для веб-приложений).
  6. websocket — один экземпляр на жизненный цикл WebSocket-сессии.

Как задать scope:

@Component
@Scope("prototype") // или @Scope(value = WebApplicationContext.SCOPE_REQUEST)
public class MyPrototypeBean { ... }
@Bean
@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
public MyService myService() {
    return new MyService();
}

Важно: Scopes singleton и prototype доступны всегда. Остальные (request, session, application, websocket) — только в веб-приложениях. Для создания кастомного scope необходимо реализовать интерфейс org.springframework.beans.factory.config.Scope.

Ответ 18+ 🔞

А, слушай, про эти ваши Spring-овские области видимости, блядь! Ну, ёпта, классика жанра, но народ постоянно путается, как эти самые scopes работают. Сейчас разжуем, как для распиздяев.

Вот представь, Spring — это такой большой, блядь, бар, а бины — это напитки. И от того, какой ты scope выберешь, зависит, нальют тебе из общего чайника или сделают новый коктейль для каждого придурка.

Стандартные шесть штук, как в лотерее, только без выигрыша:

  1. singleton — это по умолчанию, царь и бог. Контейнер создаёт один-единственный экземпляр, и все, кто его просит, получают один и тот же объект. Как водка в баре на всех. Налил в графин один раз — и все оттуда пьют. Экономия, блядь, но если кто-то туда пепел потушит, всем достанется.
  2. prototype — полная противоположность, анархия. Каждый раз, когда кто-то орёт getBean() или просит инъекцию, Spring, сука, рожает новый экземпляр. Новый стакан, новый напиток. Дорого, накладно, но зато свой, чистенький, и никто в нём не гадил.
  3. request — это уже для веб-распиздяев. Один бин на один HTTP-запрос. Пользователь нажал кнопку — тебе налили рюмку. Запрос кончился — рюмку выкинули в помойку. Кратковременная радость, блядь.
  4. session — пошире, уже на всю сессию пользователя. Пока он не закроет браузер или не выйдет по таймауту, у него своя личная бутылка. Удобно для корзины покупок, а то вдруг кто чужую телегу уведёт.
  5. application — это вообще на всю жизнь ServletContext. Один экземпляр на всё веб-приложение, но живёт в веб-слое. Как барная стойка, которая не меняется, пока бар не закроют на ремонт.
  6. websocket — новомодная хуйня для WebSocket-сессии. Пока соединение живое, бин твой. Похоже на session, но для этих ваших чатиков в реальном времени.

Как этим пользоваться, чтобы не выглядеть конченым? Вот, смотри, аннотациями всё решается, проще пареной репы.

@Component
@Scope("prototype") // Или, блядь, @Scope(value = WebApplicationContext.SCOPE_REQUEST) для веба
public class MyPrototypeBean { ... }

Или, если ты конфигурируешь всё через Java-конфиг, как серьёзный пацан:

@Bean
@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
public MyService myService() {
    return new MyService();
}

Важный момент, на котором все обжигаются, как дураки: singleton и prototype работают всегда, хоть в консоли, хоть на микроволновке. А вот request, session, application и websocket — это исключительно для веб-приложений. Без веб-контекста Spring на тебя посмотрит, как на идиота, и выбросит исключение, что твою мать.

Ну и если тебе мало этих шести и ты совсем ебнулся, можно, блядь, свой scope придумать. Надо просто интерфейс org.springframework.beans.factory.config.Scope реализовать. Но это уже для полных извращенцев, которые хотят, чтобы бин жил, например, ровно одну минуту или пересоздавался каждую пятницу. Ёперный театр, в общем.