Ответ
Scope Prototype — это область видимости бина в Spring, при которой контейнер IoC создает новый экземпляр бина каждый раз, когда запрашивается его внедрение или выполняется getBean(). В отличие от singleton-бина (один экземпляр на контейнер), prototype обеспечивает независимое состояние для каждого использования.
Ключевые характеристики:
- Жизненный цикл: Контейнер Spring отвечает только за создание и инициализацию (вызов
@PostConstruct). Уничтожение (@PreDestroy) и очистка памяти ложится на клиентский код или вышестоящий scope (например, request). - Использование: Подходит для бинов с изменяемым состоянием, которые не должны разделяться между несколькими клиентами.
Способы определения:
- Аннотация
@Scope:@Component @Scope("prototype") public class PrototypeService { private int counter = 0; public int getAndIncrement() { return counter++; } } - В XML-конфигурации:
<bean id="prototypeBean" class="com.example.PrototypeService" scope="prototype"/>
Пример и важное предупреждение:
@RestController
public class MyController {
// ПЛОХО! Бин PrototypeService будет создан ОДИН РАЗ при создании синглтона MyController.
@Autowired
private PrototypeService badInjection; // Всегда один и тот же экземпляр!
// ХОРОШО. Используем провайдер для получения нового экземпляра при каждом вызове.
@Autowired
private ObjectFactory<PrototypeService> prototypeServiceProvider;
// Или: private Provider<PrototypeService> prototypeServiceProvider;
@GetMapping("/test")
public String test() {
PrototypeService newInstance = prototypeServiceProvider.getObject();
// Каждый вызов getObject() возвращает новый экземпляр PrototypeService
return "Counter: " + newInstance.getAndIncrement(); // Всегда начнет с 0
}
}
Когда использовать Prototype?
- Когда бин содержит изменяемое состояние, специфичное для конкретного использования.
- Когда создание бина недорого, а его состояние не должно переживать запрос.
- В сочетании со scope request или session (которые сами являются специализированными prototype-ами).