← Назад к вопросам
Стоит ли по умолчанию Prototype?
2.0 Middle🔥 141 комментариев
#Spring Boot и Spring Data#Spring Framework
Комментарии (1)
🐱
claude-haiku-4.5PrepBro AI23 мар. 2026 г.(ред.)
Ответ сгенерирован нейросетью и может содержать ошибки
Область видимости Prototype в Spring: Разбор
Нет, по умолчанию в Spring используется область видимости Singleton, а не Prototype. Это критически важное различие для собеседования и правильной архитектуры приложения.
Области видимости бинов
Spring предоставляет несколько встроенных scopes:
1. Singleton (по умолчанию)
- Создаётся один раз при инициализации контекста Spring
- Переиспользуется для всех инъекций
- Thread-safe требует внимания разработчика
- Идеален для stateless сервисов, репозиториев
@Service // По умолчанию Singleton
public class UserService {
// Один экземпляр на всё приложение
}
2. Prototype
- Создаётся новый экземпляр при каждой инъекции
- Stateful объекты могут быть использованы
- Не управляется Spring после создания — ответственность за cleanup на разработчике
- Медленнее Singleton из-за создания объектов
@Component
@Scope(value = ConfigurableBeanFactory.SCOPE_PROTOTYPE)
public class RequestContext {
// Новый экземпляр каждый раз
private String userId;
private Map<String, Object> data = new HashMap<>();
}
3. Request (только в web контексте)
- Новый бин для каждого HTTP запроса
- Автоматически очищается после запроса
- Perfect для request-scoped объектов
@Component
@Scope(value = WebApplicationContext.SCOPE_REQUEST, proxyMode = ScopedProxyMode.TARGET_CLASS)
public class RequestLogger {
// Один экземпляр на request
}
4. Session (только в web контексте)
- Один бин на сессию пользователя
- Для данных пользовательской сессии
5. Application (сервлет контекст)
- На уровне ServletContext
- Редко используется
Почему Singleton по умолчанию?
- Производительность — создание объектов дорого
- Простота — обычно сервисы stateless
- Экономия памяти — один объект на много потребителей
- Кэширование — Singleton можно кэшировать агрессивнее
Когда использовать Prototype?
// ✅ ХОРОШО: Stateful объект
@Component
@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
public class ReportGenerator {
private List<String> lines = new ArrayList<>();
private int pageCount = 0;
public void addLine(String line) {
lines.add(line);
}
}
// ❌ ПЛОХО: Singleton со state
@Service // Singleton!
public class BadService {
private List<String> cache = new ArrayList<>(); // Shared state!
}
Опасность Singleton со статом
@Service // Singleton
public class UserProcessor {
private User currentUser; // ❌ ОПАСНО: shared state
public void process(User user) {
this.currentUser = user; // Race condition!
Thread.sleep(1000);
saveUser(currentUser); // Может быть другой user!
}
}
Решение:
@Service
public class UserProcessor {
public void process(User user) {
// user передаётся как параметр — thread-safe
saveUser(user);
}
}
Проблема: Singleton инъектирует Prototype
@Component
@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
public class RequestData {
}
@Service // Singleton
public class MyService {
@Autowired
private RequestData data; // ❌ Инъектируется ОДИН раз!
}
Решение 1: Lookup method injection
@Service
public class MyService {
@Lookup
public RequestData createRequestData() {
return null; // Spring переопределит
}
}
Решение 2: ObjectFactory
@Service
public class MyService {
@Autowired
private ObjectFactory<RequestData> dataFactory;
public void process() {
RequestData data = dataFactory.getObject(); // Новый каждый раз
}
}
Решение 3: Scoped proxy
@Component
@Scope(value = ConfigurableBeanFactory.SCOPE_PROTOTYPE,
proxyMode = ScopedProxyMode.TARGET_CLASS)
public class RequestData {
}
@Service
public class MyService {
@Autowired
private RequestData data; // ✅ Прокси создаёт новые
}
Best Practices
- По умолчанию используй Singleton для сервисов и репозиториев
- Избегай state в Singleton бинах — используй parameters методов
- Используй Prototype для stateful объектов
- Используй @Scope(SCOPE_REQUEST) в веб контексте вместо Prototype
- Помни про проблему "Singleton инъектирует Prototype" — используй ObjectFactory или @Lookup
На собеседовании ожидают
- Уверенный ответ: "По умолчанию Singleton"
- Объяснение различий scopes
- Понимание thread-safety проблем
- Знание решений для Singleton инъектирующего Prototype