Ответ
По умолчанию в 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 { /* Здесь можно наконец-то хранить состояние, не боясь, что его кто-то поменяет */ }
Вот и вся магия. Главное — понимать, где тебе нужен один старый пердун на всех, а где каждый раз новый, бодрый экземпляр, чтобы не было потом мучительно больно за непонятные баги.