Каков жизненный цикл контекста в Spring Framework?

«Каков жизненный цикл контекста в Spring Framework?» — вопрос из категории Spring, который задают на 10% собеседований Java Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Жизненный цикл контекста Spring (ApplicationContext) включает следующие ключевые этапы:

  1. Загрузка конфигурации и создание BeanFactory — чтение конфигурации (XML, аннотации, JavaConfig) и создание BeanDefinition для каждого бина.
  2. Создание экземпляров бинов (Instantiation) — контейнер создает экземпляры бинов в соответствии с их scope (singleton, prototype и др.).
  3. Внедрение зависимостей (Dependency Injection) — разрешение и инъекция зависимостей через конструктор, сеттеры или поля.
  4. Обработка callback-интерфейсов и аннотаций жизненного цикла — выполнение методов, помеченных как @PostConstruct, или реализующих InitializingBean.afterPropertiesSet().
  5. Обработка BeanPostProcessor — выполнение пользовательской логики до и после инициализации каждого бина (например, для проксирования через AOP).
  6. Готовность (Ready) — контекст полностью инициализирован, бины готовы к использованию.
  7. Уничтожение (Destruction) — при закрытии контекста (context.close()) вызываются методы @PreDestroy или DisposableBean.destroy().

Пример конфигурации с явным указанием методов жизненного цикла:

@Configuration
public class AppConfig {
    @Bean(initMethod = "customInit", destroyMethod = "customCleanup")
    public DataSource dataSource() {
        return new HikariDataSource();
    }
}

public class MyService {
    @PostConstruct
    public void init() {
        // Логика инициализации после инъекции зависимостей
    }
    @PreDestroy
    public void cleanup() {
        // Логика освобождения ресурсов перед уничтожением
    }
}

Почему это важно: Понимание жизненного цикла позволяет корректно управлять ресурсами (открытие/закрытие соединений), выполнять валидацию конфигурации и внедрять кастомную логику через BeanPostProcessor.