Комментарии (1)
Ответ сгенерирован нейросетью и может содержать ошибки
Scope бинов в Spring Framework
В Spring Framework по умолчанию используется singleton scope. Это означает, что один bean создаётся один раз на всё время жизни приложения и переиспользуется во все местах.
Singleton (по умолчанию)
Singleton scope — это scope по умолчанию. Spring создаёт один экземпляр bean и повторно использует его для всех запросов.
// Явное указание Singleton (по умолчанию)
@Bean
@Scope("singleton")
public UserService userService() {
return new UserService();
}
// Или просто (по умолчанию — singleton)
@Bean
public UserService userService() {
return new UserService();
}
// Проверка: оба экземпляра будут одинаковые
UserService service1 = context.getBean(UserService.class);
UserService service2 = context.getBean(UserService.class);
System.out.println(service1 == service2); // true
Характеристики Singleton:
- Один экземпляр на всё приложение
- Инстанцирование при старте приложения
- Потокобезопасность требует синхронизации
- Экономит память
- Идеален для stateless объектов (сервисов)
Prototype
Prototype scope — для каждого запроса создаётся новый экземпляр bean.
@Bean
@Scope("prototype")
public RequestData requestData() {
return new RequestData();
}
// Проверка: экземпляры будут разные
RequestData data1 = context.getBean(RequestData.class);
RequestData data2 = context.getBean(RequestData.class);
System.out.println(data1 == data2); // false
Характеристики Prototype:
- Новый экземпляр при каждом запросе
- Инстанцирование при запросе bean
- Потокобезопасен по природе
- Больше памяти
- Идеален для stateful объектов
Веб-приложение: Request Scope
Request scope используется в веб-приложениях. Bean живёт во время одного HTTP запроса.
@Component
@Scope("request")
public RequestContext requestContext() {
return new RequestContext();
}
// В контроллере
@RestController
public class UserController {
@Autowired
private RequestContext requestContext;
@GetMapping("/users/{id}")
public User getUser(@PathVariable Long id) {
// requestContext существует только во время этого запроса
return userService.findById(id);
}
}
Характеристики Request Scope:
- Один bean на HTTP запрос
- Создание при начале запроса
- Уничтожение в конце запроса
- Идеален для хранения данных запроса
- Требует Web контекст (ServletContext)
Session Scope
Session scope — bean живёт во время сессии пользователя.
@Component
@Scope("session")
public UserSession userSession() {
return new UserSession();
}
// В контроллере
@RestController
public class ProfileController {
@Autowired
private UserSession userSession;
@GetMapping("/profile")
public UserInfo getProfile() {
// userSession существует для каждой сессии
return userSession.getCurrentUser();
}
}
Характеристики Session Scope:
- Один bean на пользовательскую сессию
- Создание при первом обращении в сессии
- Уничтожение при завершении сессии
- Хранит данные пользователя
- Требует Web контекст
Application Scope
Application scope — один bean на приложение в веб-контексте (как servlet scope).
@Component
@Scope(WebApplicationContext.SCOPE_APPLICATION)
public AppConfig appConfig() {
return new AppConfig();
}
Это похоже на singleton, но специфично для веб-контекста.
Custom Scope
Можно создать свой scope.
@Configuration
public class CustomScopeConfig {
@Bean
public CustomScope customScope() {
return new CustomScope();
}
@Bean
public static CustomScopeConfigurer customScopeConfigurer() {
CustomScopeConfigurer configurer = new CustomScopeConfigurer();
configurer.addScope("custom", customScope());
return configurer;
}
}
// Использование
@Component
@Scope("custom")
public MyBean myBean() {
return new MyBean();
}
ScopedProxyMode
Для внедрения shorter-lived bean в longer-lived bean используется proxy:
@Component
@Scope(value = "request", proxyMode = ScopedProxyMode.TARGET_CLASS)
public RequestData requestData() {
return new RequestData();
}
// Singleton сервис может внедрить request-scoped bean
@Service
public class MyService {
@Autowired
private RequestData requestData; // Proxy к request bean
}
Таблица Scopes
| Scope | Жизненный цикл | Количество | Использование |
|---|---|---|---|
| Singleton | Приложение | 1 на приложение | Сервисы, репозитории |
| Prototype | Запрос | Новый каждый раз | Stateful объекты |
| Request | HTTP запрос | 1 на запрос | Контекст запроса |
| Session | Пользовательская сессия | 1 на сессию | Данные пользователя |
| Application | Приложение (веб) | 1 на приложение | Конфигурация |
Примеры использования
Singleton (по умолчанию) — сервис
@Service
public class UserService {
// Автоматически Singleton
// Безопасен, если нет состояния
public User findById(Long id) {
// Статические методы или доступ к БД
return userRepository.findById(id).orElse(null);
}
}
Prototype — для временных объектов
@Component
@Scope("prototype")
public DataProcessor {
private List<String> buffer = new ArrayList<>();
// Новый экземпляр каждый раз, состояние изолировано
public void process(String data) {
buffer.add(data);
}
}
Request — для контекста запроса
@Component
@Scope("request")
public HttpContext {
private String userId;
private String requestId;
// Данные только для этого запроса
}
Лучшие практики
- По умолчанию используйте Singleton — большинство бинов должны быть stateless
- Prototype только если нужно — для действительно stateful объектов
- Request scope в веб-приложениях — для изоляции данных запроса
- Избегайте состояния в Singleton — используйте параметры методов
- Используйте proxy для混合 scopes — когда shorter-lived внедрять в longer-lived
Проверка scope bean
ConfigurableListableBeanFactory beanFactory = context.getBeanFactory();
BeanDefinition definition = beanFactory.getBeanDefinition("myBean");
String scope = definition.getScope();
System.out.println("Bean scope: " + scope); // singleton, prototype и т.д.
Вывод: По умолчанию Spring использует Singleton scope для всех бинов. Это означает, что один экземпляр bean создаётся один раз при запуске приложения и переиспользуется везде. Это оптимально для stateless сервисов и экономит память. Для других случаев доступны Prototype, Request, Session и другие scopes.