Создан ли экземпляр бина к моменту вызова методов BeanPostProcessor в Spring?

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

Ответ

Да, экземпляр (объект) уже создан. BeanPostProcessor работает с существующими экземплярами бинов, но вмешивается в процесс их инициализации.

Жизненный цикл создания бина и BeanPostProcessor:

  1. Создание экземпляра (вызов конструктора).
  2. Внедрение зависимостей (популяция полей, сеттеры).
  3. postProcessBeforeInitialization() — вызывается после внедрения зависимостей, но до любых методов инициализации (например, @PostConstruct, InitializingBean.afterPropertiesSet()).
  4. Вызов методов инициализации (@PostConstruct и др.).
  5. postProcessAfterInitialization() — вызывается после всех методов инициализации. Возвращаемый объект становится готовым бин-синглтоном.

Пример реализации:

@Component
public class CustomBeanPostProcessor implements BeanPostProcessor {
    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) {
        // Объект 'bean' уже создан, его зависимости внедрены.
        // Можно модифицировать или обернуть бин перед init.
        System.out.println("Before init for bean: " + beanName);
        return bean; // или его прокси/обёртку
    }

    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) {
        // Бин полностью проинициализирован.
        System.out.println("After init for bean: " + beanName);
        return bean;
    }
}

Практическое применение: BeanPostProcessor используется для низкоуровневых модификаций бинов, например, для создания прокси (как в Spring AOP), проверки аннотаций или внедрения дополнительной логики.