Комментарии (1)
Ответ сгенерирован нейросетью и может содержать ошибки
Scope бинов в Spring Framework
Scope бина — это управление жизненным циклом и видимостью объекта в Spring контексте. Spring определяет, как долго существует экземпляр бина и сколько экземпляров будет создано.
Основные типы scope
1. Singleton (по умолчанию)
Создается один экземпляр на весь контекст приложения. Используется для stateless объектов (сервисы, репозитории).
@Component
@Scope("singleton")
public class UserService {
public void processUser(String name) {
// один экземпляр на всё приложение
}
}
2. Prototype
Новый экземпляр создается при каждом запросе. Используется для stateful объектов.
@Component
@Scope("prototype")
public class RequestData {
private String data;
// новый экземпляр для каждого запроса
}
3. Request (web-приложения)
Новый экземпляр на каждый HTTP запрос. Доступен только в ServletRequest контексте.
@Component
@Scope("request")
public class HttpRequestHandler {
@Autowired
private HttpServletRequest request; // доступен в scope request
}
4. Session (web-приложения)
Один экземпляр на HTTP сессию пользователя. Сохраняется между запросами одного пользователя.
@Component
@Scope("session")
public class UserSession {
private String userId;
// один экземпляр на сессию пользователя
}
5. Application/ServletContext
Один экземпляр на ServletContext (в web-приложении).
@Component
@Scope("application")
public class AppConfig {
// один на всё web-приложение
}
Проблема Singleton injection в Prototype
Есть подводная камень: если singleton зависит от prototype бина, prototype будет внедрён один раз при создании singleton.
@Component
@Scope("singleton")
public class SingletonService {
@Autowired
private PrototypeService prototypeService; // внедрится один раз!
}
@Component
@Scope("prototype")
public class PrototypeService {
// нужен новый экземпляр каждый раз
}
Решение — использовать ObjectProvider или @Lookup:
@Component
public class SingletonService {
@Autowired
private ObjectProvider<PrototypeService> prototypeProvider;
public void process() {
PrototypeService service = prototypeProvider.getObject(); // новый экземпляр
}
}
Или через @Lookup:
@Component
public class SingletonService {
@Lookup
protected PrototypeService getPrototype() {
return null; // Spring переопределит на получение нового экземпляра
}
}
Выбор scope
- Singleton: сервисы, репозитории, utility классы (stateless)
- Prototype: объекты состояния, DTO, одноразовые обработчики
- Request/Session: веб-компоненты, привязанные к запросу/сессии
Правильный выбор scope критичен для производительности (singleton экономит память) и корректности (prototype избегает race conditions).