Вопрос проверяет понимание жизненного цикла бинов в Spring и различий между scope’ами.
Для бинов со scope prototype Spring не управляет полным жизненным циклом. Контейнер отвечает только за создание и внедрение зависимостей. Уничтожение prototype-бина находится на ответственности пользователя. Поэтому @PreDestroy для таких бинов не вызывается автоматически. Это ожидаемое поведение Spring.
Причина связана с архитектурой контейнера Spring и ответственностью за ресурсы.
Prototype scope — это scope, при котором новый экземпляр бина создаётся при каждом запросе из контейнера.
Spring по-разному работает с разными scope.
Singleton
Создание
Инициализация
Уничтожение (@PreDestroy)
Prototype
Только создание
Инициализация
Дальнейшая судьба неизвестна контейнеру
@PreDestroy не вызываетсяSpring не знает:
сколько живёт объект
кто и где его использует
когда он больше не нужен
Из-за этого:
Контейнер не хранит ссылки на prototype-бины
Не может отследить момент уничтожения
Не вызывает @PreDestroy
@Scope("prototype")
@Component
class ResourceHolder {
@PreDestroy
void close() {
// не будет вызвано автоматически
}
}
Возможные подходы:
Управлять жизненным циклом вручную
Использовать DisposableBean явно
Оборачивать prototype в singleton
Использовать @Bean(destroyMethod = ...) при явном управлении
Prototype-бин живёт вне контроля контейнера после создания. Поэтому освобождение ресурсов — ответственность кода, который его использует.