Получить доступ

Что такое BeanPostProcessor и зачем он нужен?

MiddleКонтейнер изнутриSpring
Ещё спрашивают так:
  • Как Spring создаёт прокси для @Transactional?
  • Чем BeanPostProcessor отличается от BeanFactoryPostProcessor?
Коротко

BeanPostProcessor вызывается для каждого бина до и после инициализации и может изменить или заменить объект — так появляются прокси для @Transactional, @Async, AOP и обрабатываются @Autowired, @PostConstruct.

  • postProcessBeforeInitialization — до @PostConstruct, postProcessAfterInitialization — после
  • BeanFactoryPostProcessor работает раньше — с определениями бинов, а не с объектами (например, подстановка ${…})
  • Свои — для сквозной инфраструктуры; в бизнес-коде почти не нужны

А ещё BPP сам создаётся рано, и его зависимости не проходят через другие BPP

Так подсказку видит пользователь sotto на живом собеседовании — за пару секунд, пока вы думаете вслух.

Подробно

Где в цикле: после создания объекта и внедрения зависимостей контейнер вызывает для каждого бина:

  1. postProcessBeforeInitialization(bean, name) у всех BeanPostProcessor;
  2. методы инициализации (@PostConstruct, afterPropertiesSet, initMethod);
  3. postProcessAfterInitialization(bean, name) — результат и становится бином в контексте.

Что на них построено:

  • AutowiredAnnotationBeanPostProcessor — внедрение @Autowired, @Value;
  • CommonAnnotationBeanPostProcessor — @PostConstruct, @PreDestroy;
  • AbstractAutoProxyCreator (AOP) — в after-фазе оборачивает бин прокси, если к нему применимы аспекты: @Transactional, @Async, @Cacheable. Поэтому в контексте лежит не ваш объект, а прокси.

BeanFactoryPostProcessor работает раньше — когда есть только определения бинов (BeanDefinition), объектов ещё нет. Может менять метаданные: PropertySourcesPlaceholderConfigurer подставляет ${...}, ConfigurationClassPostProcessor разбирает @Configuration и @Bean.

Свой BPP — для инфраструктуры: регистрация бинов определённого типа в реестре, обёртка метриками. Подводные камни: BPP создаются до остальных бинов, поэтому бины, от которых зависит BPP, создаются рано и могут не получить прокси (сообщение «is not eligible for getting processed by all BeanPostProcessors»).

Что хотят услышать

  • Когда вызывается и что может сделать.
  • Примеры: внедрение, @PostConstruct, прокси.
  • Отличие от BeanFactoryPostProcessor.

Частые ошибки

  • Писать BPP для бизнес-логики.

Проверьте себя

Один верный вариант. Подумайте, потом откройте ответ.

Показать варианты и ответ
  • ✗Класс, создающий пул соединений к БД
  • ✗Аннотация для валидации DTO
  • ✓Точка расширения, вмешивающаяся до/после инициализации каждого бина; через неё навешиваются прокси (AOP, @Transactional)
  • ✗Механизм только для логирования

Что спросят дальше

  • Чем BeanFactoryPostProcessor отличается?
  • Почему @Transactional создаёт proxy?

Разбор темы

Связанные вопросы

Закрытая бета

Подсказки на собеседовании — в реальном времени

sotto слышит вопрос интервьюера и показывает короткий ответ и план, как в блоке «Коротко». Оставьте контакт — пришлём доступ и промокод.

  • Промокод на 2 часа — сверх пробных 30 минут
  • Программа для Windows — скачать сразу, войти — через Яндекс ID или VK ID
  • Прямая связь с разработчиком: что улучшить — сделаем