Я изучаю сертификацию Spring Core, и у меня есть некоторые сомнения относительно того, как Spring обрабатывает жизненный цикл bean-компонентов и, в частности, постпроцессор bean-компонентов .
Итак, у меня есть эта схема:
Для меня довольно ясно, что это значит:
На этапе загрузки определений компонентов выполняются следующие шаги :
В @Configuration классы обрабатываются и / или @Components проверяются на наличие и / или файлы XML обрабатываются.
Определения компонентов, добавленные в BeanFactory (каждое проиндексировано под своим идентификатором)
Вызываются специальные bean- компоненты BeanFactoryPostProcessor , они могут изменять определение любого bean-компонента (например, для замены значений свойств-заполнителей).
Затем на этапе создания bean-компонентов выполняются следующие шаги :
Каждый bean-компонент активно создается по умолчанию (создается в правильном порядке с введенными зависимостями).
После внедрения зависимости каждый компонент проходит стадию постобработки, на которой может происходить дальнейшая настройка и инициализация.
После постобработки компонент полностью инициализирован и готов к использованию (отслеживается по его идентификатору до тех пор, пока контекст не будет уничтожен)
Хорошо, для меня это довольно ясно, и я также знаю, что есть два типа постпроцессоров bean-компонентов :
Инициализаторы: инициализируйте bean-компонент, если это указано (например, @PostConstruct).
и все остальное: которые позволяют дополнительную настройку и могут выполняться до или после шага инициализации.
И выкладываю этот слайд:
Поэтому мне очень ясно, что инициализаторы bean- постпроцессоры (это методы, аннотированные аннотацией @PostContruct и автоматически вызываемые сразу после методов установки (то есть после внедрения зависимости), и я знаю, что могу использовать для выполнить некоторый пакет инициализации (как и заполнить кеш, как в предыдущем примере).
Но что именно представляет собой другой постпроцессор bean-компонентов? Что мы имеем в виду, когда говорим, что эти шаги выполняются до или после фазы инициализации ?
Итак, мои bean-компоненты создаются, и их зависимости вводятся, поэтому фаза инициализации завершается (путем выполнения аннотированного метода @PostContruct ). Что мы имеем в виду, говоря, что Bean Post Processor используется до фазы инициализации? Значит, это происходит до выполнения аннотированного метода @PostContruct ? Означает ли это, что это могло произойти до внедрения зависимости (до этого вызываются методы установки)?
И что именно мы имеем в виду, когда говорим, что это выполняется после этапа инициализации . Значит, это происходит после выполнения аннотированного метода @PostContruct , что ли?
Я легко могу понять, почему мне нужен аннотированный метод @PostContruct, но я не могу представить типичный пример другого типа постпроцессора bean, не могли бы вы показать мне типичный пример того, когда они используются?
источник
Ответы:
Документ Spring объясняет BPP в разделе Настройка bean-компонентов с помощью BeanPostProcessor . Бины BPP - это особый вид бинов, которые создаются раньше любых других бинов и взаимодействуют с вновь созданными бинами. Благодаря этой конструкции Spring дает вам возможность подключиться и настроить поведение жизненного цикла, просто реализовав
BeanPostProcessor
собственный.Имея собственный BPP, например
public class CustomBeanPostProcessor implements BeanPostProcessor { public CustomBeanPostProcessor() { System.out.println("0. Spring calls constructor"); } @Override public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { System.out.println(bean.getClass() + " " + beanName); return bean; } @Override public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { System.out.println(bean.getClass() + " " + beanName); return bean; } }
будет вызываться и распечатывать имя класса и bean для каждого созданного bean.
Чтобы понять, как метод соответствует жизненному циклу bean-компонента и когда именно вызывается метод, проверьте документацию
Важным моментом также является то, что
Что касается связи с
@PostConstruct
примечанием, что эта аннотация является удобным способом объявленияpostProcessAfterInitialization
метода, и Spring узнает об этом, когда вы либо регистрируете,CommonAnnotationBeanPostProcessor
либо указываете<context:annotation-config />
файл конфигурации in bean. Будет ли@PostConstruct
метод выполняться до или после любого другого,postProcessAfterInitialization
зависит отorder
свойстваисточник
Типичный пример постпроцессора bean - это когда вы хотите обернуть исходный bean-компонент в экземпляр прокси, например, при использовании
@Transactional
аннотации.Постпроцессору bean-компонента будет передан исходный экземпляр bean-компонента, он может вызывать любые методы на цели, но он также должен возвращать фактический экземпляр bean-компонента, который должен быть привязан в контексте приложения, что означает, что он может фактически вернуть объект он хочет. Типичный сценарий, когда это полезно, - это когда постпроцессор bean-компонента оборачивает цель в экземпляр прокси. Все вызовы bean-компонента, привязанного к контексту приложения, будут проходить через прокси, а затем прокси-сервер сможет выполнить некоторую магию до и / или после вызовов целевого bean-компонента, например, АОП или управление транзакциями.
источник
Разница в том, что
BeanPostProcessor
будет подключаться инициализация контекста, а затем вызовpostProcessBeforeInitialization
иpostProcessAfterInitialization
для всех определенных компонентов.Но
@PostConstruct
используется только для конкретного класса, для которого вы хотите настроить создание компонента после конструктора или метода установки.источник