← Назад к вопросам
Будет ли вызван метод, помеченный как Prototype с аннотацией PreDestroy?
2.2 Middle🔥 111 комментариев
#Spring Boot и Spring Data#Spring Framework
Комментарии (1)
🐱
claude-haiku-4.5PrepBro AI22 мар. 2026 г.(ред.)
Ответ сгенерирован нейросетью и может содержать ошибки
@PreDestroy для Prototype бинов
Ответ: Нет, метод с аннотацией @PreDestroy не будет вызван для бинов со скопом Prototype.
Это важное различие в жизненном цикле Spring бинов, которое часто упускают при разработке.
Почему это происходит?
Spring контейнер полностью управляет жизненным циклом Singleton бинов (скоп по умолчанию). Для них контейнер:
- Создаёт экземпляр при инициализации
- Вызывает
@PostConstructметоды - При завершении приложения вызывает
@PreDestroyметоды
Для Prototype бинов ситуация иная:
@Component
@Scope("prototype")
public class PrototypeBean {
@PostConstruct
public void init() {
System.out.println("PostConstruct вызван");
}
@PreDestroy
public void destroy() {
System.out.println("PreDestroy НЕ будет вызван!");
}
}
Жизненный цикл Prototype
- Создание: Spring создаёт новый экземпляр при каждом запросе
getBean() - @PostConstruct: Вызывается один раз при создании
- Использование: Бин передаётся клиенту
- Ответственность передаётся: Spring больше не управляет этим объектом
- @PreDestroy: Не вызывается — это задача клиента
Сравнение скопов
// Singleton - управляется Spring полностью
@Component
public class SingletonBean {
@PostConstruct // ✓ Вызовется
public void init() { }
@PreDestroy // ✓ Вызовется при shutdown
public void destroy() { }
}
// Prototype - Spring только создаёт
@Component
@Scope("prototype")
public class PrototypeBean {
@PostConstruct // ✓ Вызовется при создании
public void init() { }
@PreDestroy // ✗ Не вызовется!
public void destroy() { }
}
Как реализовать очистку для Prototype?
Используй интерфейс BeanFactory с getBean() и сам управляй жизненным циклом:
@Component
public class PrototypeConsumer {
@Autowired
private BeanFactory beanFactory;
public void useBean() {
PrototypeBean bean = beanFactory.getBean(PrototypeBean.class);
try {
// работа с бином
} finally {
// Нужно вызвать destroy() самостоятельно
bean.destroy();
}
}
}
Или используй DisposableBean интерфейс для более явного управления:
@Component
@Scope("prototype")
public class PrototypeBean implements DisposableBean {
@Override
public void destroy() throws Exception {
System.out.println("Явное очистка");
}
}
Вывод
Для Prototype бинов Spring не гарантирует вызов @PreDestroy, так как контейнер передаёт ответственность управления жизненным циклом клиентскому коду. Разработчик должен сам позаботиться об очистке ресурсов.