Что такое BeanPostProcessor и зачем он нужен?
- Как Spring создаёт прокси для @Transactional?
- Чем BeanPostProcessor отличается от BeanFactoryPostProcessor?
BeanPostProcessor вызывается для каждого бина до и после инициализации и может изменить или заменить объект — так появляются прокси для @Transactional, @Async, AOP и обрабатываются @Autowired, @PostConstruct.
- postProcessBeforeInitialization — до @PostConstruct, postProcessAfterInitialization — после
- BeanFactoryPostProcessor работает раньше — с определениями бинов, а не с объектами (например, подстановка ${…})
- Свои — для сквозной инфраструктуры; в бизнес-коде почти не нужны
А ещё BPP сам создаётся рано, и его зависимости не проходят через другие BPP
Подробно
Где в цикле: после создания объекта и внедрения зависимостей контейнер вызывает для каждого бина:
postProcessBeforeInitialization(bean, name)у всех BeanPostProcessor;- методы инициализации (
@PostConstruct,afterPropertiesSet,initMethod); 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
- ✗Механизм только для логирования создания бинов
- ✓Хук до и после инициализации каждого бина; через него навешивают прокси
Что спросят дальше
- Чем BeanFactoryPostProcessor отличается?
- Почему @Transactional создаёт proxy?
Разбор темы
- Контейнер: события, FactoryBean и тонкое связывание
События приложения и @EventListener, FactoryBean, Aware-интерфейсы, порядок бинов (@Order/@DependsOn) и отложенное получение (ObjectProvider/@Lazy/@Lookup).
Связанные вопросы
Разбор собеседования с sotto
После собеседования sotto разбирает разговор: оценка, каждый вопрос — хорошо, частично или слабо, чего не хватило в ответе и над чем поработать к следующему разу. Первые 30 минут бесплатно.