Карта / Spring Core / Жизненный цикл бина

Жизненный цикл бина

Бин проходит через несколько этапов от создания до уничтожения, и 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. Очистка — закрываем соединение");
    }
}
Копнуть глубже

Полная последовательность жизненного цикла:

  1. Контейнер создаёт объект (вызывается конструктор);
  2. Внедряются зависимости (через конструктор или @Autowired на полях/методах);
  3. Вызывается @PostConstruct — место для инициализации, требующей уже готовых зависимостей;
  4. Бин готов к работе, используется приложением;
  5. При остановке приложения вызывается @PreDestroy — место для освобождения ресурсов (закрыть соединения, остановить потоки).

Зачем @PostConstruct, если можно просто написать логику в конструкторе. В конструкторе зависимости ещё не обязательно полностью готовы (особенно если внедрение идёт через поля/сеттеры, а не через конструктор) — @PostConstruct гарантированно вызывается после того, как все зависимости уже внедрены, это безопаснее для инициализационной логики, которая на них опирается.

@PreDestroy критичен для освобождения ресурсов — соединения с базой, файловые дескрипторы, потоки. Без аккуратного закрытия при остановке приложения это приводит к утечкам ресурсов даже при штатном завершении работы.

🎤 Закрыл тему, если можешь объяснить:
• основные этапы жизни бина от создания до уничтожения;
• зачем нужны `@PostConstruct` и `@PreDestroy`, а не просто конструктор (если дошёл до 2-го слоя).