Жизненный цикл бина
Бин проходит через несколько этапов от создания до уничтожения, и Spring даёт возможность вмешаться в каждый из них.
@Component
class DatabaseConnection {
DatabaseConnection() {
System.out.println("1. Конструктор — объект создан");
}
@Autowired
void injectDependencies() {
System.out.println("2. Зависимости внедрены");
}
@PostConstruct // после внедрения всех зависимостей
void init() {
System.out.println("3. Инициализация — подключаемся к БД");
}
@PreDestroy // перед уничтожением бина (при остановке приложения)
void cleanup() {
System.out.println("4. Очистка — закрываем соединение");
}
}
Копнуть глубже
Полная последовательность жизненного цикла:
- Контейнер создаёт объект (вызывается конструктор);
- Внедряются зависимости (через конструктор или
@Autowiredна полях/методах); - Вызывается
@PostConstruct— место для инициализации, требующей уже готовых зависимостей; - Бин готов к работе, используется приложением;
- При остановке приложения вызывается
@PreDestroy— место для освобождения ресурсов (закрыть соединения, остановить потоки).
Зачем @PostConstruct, если можно просто написать логику в конструкторе. В конструкторе зависимости ещё не обязательно полностью готовы (особенно если внедрение идёт через поля/сеттеры, а не через конструктор) — @PostConstruct гарантированно вызывается после того, как все зависимости уже внедрены, это безопаснее для инициализационной логики, которая на них опирается.
@PreDestroy критичен для освобождения ресурсов — соединения с базой, файловые дескрипторы, потоки. Без аккуратного закрытия при остановке приложения это приводит к утечкам ресурсов даже при штатном завершении работы.
🎤 Закрыл тему, если можешь объяснить:
• основные этапы жизни бина от создания до уничтожения;
• зачем нужны `@PostConstruct` и `@PreDestroy`, а не просто конструктор (если дошёл до 2-го слоя).
• зачем нужны `@PostConstruct` и `@PreDestroy`, а не просто конструктор (если дошёл до 2-го слоя).