Какой scope у бина используется в Spring по умолчанию?

Ответ

По умолчанию в Spring все бины имеют scope singleton.

Что это означает: Контейнер Spring IoC создает и возвращает один и тот же экземпляр бина при каждом запросе или внедрении зависимости.

Пример бина по умолчанию:

@Component // Или @Service, @Repository, @Controller
public class DefaultSingletonService {
    // Этот бин будет существовать в единственном экземпляре в контексте приложения
}

Другие доступные scopes в Spring:

  • prototype – новый экземпляр создается при каждом запросе бина.
  • request – экземпляр живет в рамках одного HTTP-запроса (только для веб-приложений).
  • session – экземпляр живет в рамках HTTP-сессии пользователя (только для веб-приложений).
  • application – экземпляр живет в рамках ServletContext (аналог singleton, но с семантикой веб-уровня).
  • websocket – экземпляр живет в рамках сессии WebSocket.

Как изменить scope: Используйте аннотацию @Scope.

@Component
@Scope("prototype")
public class PrototypeService { /* Новый экземпляр при каждом инжекте */ }

Ответ 18+ 🔞

Давай разжую эту тему, как будто это последний кусок мяса в тарелке. Смотри, в Спринге, если ты не указал ничего особенного, все твои бины — они как одинокий носок в стиральной машине: один и тот же на протяжении всей жизни приложения. Это называется singleton, и контейнер IoC, этот хитрожопый менеджер, будет подсовывать тебе один и тот же экземпляр каждый раз, когда ты его просишь или когда он тебе сам впендюривается как зависимость.

Что это, блядь, значит на практике: Попросил бин — получил тот же самый объект. Ещё раз попросил — опять он, старый знакомый. Как будто один тапок на всю квартиру.

Вот тебе пример, стандартный, как кирпич:

@Component // Или @Service, @Repository, @Controller — не суть
public class DefaultSingletonService {
    // Этот чувак будет один на весь контекст. Как царь и бог.
}

Но жизнь, ёпта, не чёрно-белая! Есть и другие скусы, на любой вкус и цвет:

  • prototype – А вот это уже интереснее! Каждый раз, когда ты тянешься за этим бином, Spring, как заботливая мамаша, лепит тебе свеженький, новый экземпляр. Никакого повторного использования — только хардкор.
  • request – Экземпляр живёт ровно столько, сколько длится один HTTP-запрос. Сделал запрос — родился бин. Получил ответ — бин отправился в мир иной. Только для веба.
  • session – Тут бин привязывается к сессии пользователя. Залогинился — бин родился. Разлогинился или сессия сдохла — бин, ясное дело, накрылся медным тазом. Тоже веб-история.
  • application – Почти как синглтон, но с веб-флёром. Живёт в рамках ServletContext. Разница тонкая, но она есть, поверь.
  • websocket – Для современных штук. Бин живёт, пока живет соединение по WebSocket'у.

Хочешь поменять скус? Легко! Берёшь аннотацию @Scope и тычешь её в бин.

@Component
@Scope("prototype") // Вот теперь каждый раз новый!
public class PrototypeService { /* Здесь можно наконец-то хранить состояние, не боясь, что его кто-то поменяет */ }

Вот и вся магия. Главное — понимать, где тебе нужен один старый пердун на всех, а где каждый раз новый, бодрый экземпляр, чтобы не было потом мучительно больно за непонятные баги.