Комментарии (1)
Ответ сгенерирован нейросетью и может содержать ошибки
Области видимости (Scopes) Bean в Spring Framework
Bean scope — это период жизни бина в контейнере Spring и правила его создания и переиспользования. Понимание скоупов критично для разработки на Spring, так как они влияют на производительность, потокобезопасность и поведение приложения.
1. Singleton (по умолчанию)
Самый часто используемый scope. Контейнер создает один экземпляр бина на все приложение и переиспользует его:
@Component
public class UserService {
// Singleton по умолчанию
}
// Или явно:
@Bean
@Scope("singleton")
public UserService userService() {
return new UserService();
}
Характеристики:
- Один экземпляр на контекст приложения
- Потокобезопасный доступ требует внимания (может быть конкурентный доступ)
- Эффективен по памяти
Когда использовать: для stateless сервисов (UserService, DatabaseService)
2. Prototype
Контейнер создает новый экземпляр каждый раз при запросе:
@Component
@Scope("prototype")
public class RequestData {
// Новый экземпляр при каждом запросе
}
Характеристики:
- Новый объект на каждый запрос
- Не переиспользуется
- Каждый объект имеет собственное состояние
Когда использовать: для stateful объектов, которые хранят данные конкретного запроса
3. Request
Для веб-приложений. Контейнер создает новый бин для каждого HTTP запроса:
@Component
@Scope("request")
public class HttpRequestData {
// Живет во время одного HTTP запроса
}
Характеристики:
- Один экземпляр на HTTP запрос
- Автоматически уничтожается после завершения запроса
- Доступен только в веб-контексте
Когда использовать: для данных, специфичных для одного HTTP запроса
4. Session
Для веб-приложений. Контейнер создает новый бин для каждой HTTP сессии:
@Component
@Scope("session")
public class UserSession {
private User currentUser;
// Живет во время сессии пользователя
}
Характеристики:
- Один экземпляр на HTTP сессию
- Сохраняется между запросами одного пользователя
- Уничтожается при завершении сессии
Когда использовать: для данных о текущем пользователе, предпочтения
5. Application (ServletContext)
Один бин на весь сервлет контекст приложения:
@Component
@Scope("application")
public class ApplicationConfig {
// Один экземпляр на приложение
}
Когда использовать: для глобальной конфигурации приложения
6. WebSocket
Один бин на WebSocket сессию (Spring 4.0+):
@Component
@Scope("websocket")
public class WebSocketHandler {
// Один экземпляр на WebSocket соединение
}
Пример практического использования
// UserService — Singleton (stateless)
@Service
public class UserService {
private final UserRepository userRepository;
public User getUserById(Long id) {
return userRepository.findById(id).orElse(null);
}
}
// RequestData — Request scope (stateful)
@Component
@Scope("request")
public class RequestContext {
private String requestId = UUID.randomUUID().toString();
private long startTime = System.currentTimeMillis();
public void logRequest() {
System.out.println("Request: " + requestId + ", Time: " + startTime);
}
}
// UserCart — Session scope
@Component
@Scope("session")
public class ShoppingCart {
private List<Product> items = new ArrayList<>();
public void addItem(Product product) {
items.add(product);
}
}
Таблица сравнения
| Scope | Кол-во экземпляров | Жизненный цикл | Потокобезопасность |
|---|---|---|---|
| Singleton | 1 на приложение | Приложение | Требует синхронизации |
| Prototype | 1 на каждый запрос | Каждый запрос | Безопасен |
| Request | 1 на HTTP запрос | HTTP запрос | Безопасен |
| Session | 1 на сессию | Сессия | Безопасен |
Важные моменты
- Singleton автоматический: не указываете scope = используется singleton
- Потокобезопасность: singleton бины будут вызваны из разных потоков
- Dependency Injection: можно инжектить бины разных скоупов (с ограничениями)
- ProxyMode: для инжекции prototype в singleton используйте
proxyMode = ScopedProxyMode.TARGET_CLASS
@Bean
@Scope(value = "prototype", proxyMode = ScopedProxyMode.TARGET_CLASS)
public Prototype prototypeBean() {
return new Prototype();
}