Какие ключевые сущности Spring Framework участвуют в создании бина?

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

Ответ

Процесс создания бина в Spring включает несколько ключевых сущностей, которые взаимодействуют на разных этапах жизненного цикла:

Основные компоненты:

  1. BeanDefinition — содержит метаданные бина: класс, scope (singleton, prototype), ленивую инициализацию (lazy-init), зависимости и свойства.
  2. BeanFactory — базовый интерфейс IoC-контейнера, отвечающий за создание и управление бинами.
  3. ApplicationContext — расширенный контейнер, наследующий BeanFactory, добавляющий поддержку AOP, международализации, событий и многое другое.
  4. BeanPostProcessor — интерфейс для кастомизации бинов после их инстанцирования, но до/после инициализации (например, @PostConstruct).
  5. BeanFactoryPostProcessor — интерфейс для модификации BeanDefinition до создания экземпляров бинов.

Пример кастомизации через BeanPostProcessor:

@Component
public class CustomBeanPostProcessor implements BeanPostProcessor {
    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) {
        // Логика, выполняемая ДО вызова методов инициализации бина
        System.out.println("Before init for bean: " + beanName);
        return bean;
    }

    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) {
        // Логика, выполняемая ПОСЛЕ инициализации бина
        return bean;
    }
}

Типичный порядок создания бина:

  1. Загрузка и парсинг BeanDefinition.
  2. Применение BeanFactoryPostProcessor (если есть).
  3. Инстанцирование (создание экземпляра через конструктор или фабричный метод).
  4. Внедрение зависимостей (пополнение полей, сеттеры).
  5. Применение BeanPostProcessor.postProcessBeforeInitialization.
  6. Инициализация (вызов методов, помеченных @PostConstruct, или InitializingBean.afterPropertiesSet()).
  7. Применение BeanPostProcessor.postProcessAfterInitialization.
  8. Бин готов к использованию. Для singleton-бинов помещается в кэш.