Как точно работает почтовый процессор Spring bean?
Я изучаю для сертификации Spring Core, у меня есть некоторые сомнения относительно того, как Spring обрабатывает жизненный цикл beans и, в частности, о постпроцессоре bean/STRONG > .
Итак, у меня есть эта схема:
![enter image description here]()
Для меня довольно ясно, что это значит:
В фазу Загрузить Bean Определения происходит следующее:
-
Обработаны классы @Configuration и/или @Components.
отсканированные и/или XML файлы.
-
bean определения, добавленные в BeanFactory (каждый индексируется под его идентификатором)
-
Вызывается специальный BeanFactoryPostProcessor beans, он может модифицировать определение любого Bean (например, для замены значений свойств-заполнителей).
Затем на этапе beans происходит следующее:
-
Каждый Bean сгенерирован по умолчанию (создается в правильном порядке с вложенными зависимостями).
-
После инъекции зависимостей каждый Bean проходит постобработку
фазу, в которой могут возникнуть дополнительные конфигурации и инициализации.
-
После пост-обработки Bean полностью инициализируется и готово к использованию (отслеживается по его идентификатору до тех пор, пока контекст не будет уничтожен)
Хорошо, это довольно ясно для меня, и я также знаю, что есть два типа пост-процессоров Bean, которые:
-
Инициализаторы: Инициализируйте Bean, если это указано (т.е. @PostConstruct).
-
Все остальные:, которые позволяют выполнить дополнительную настройку и что может выполняться до или после этапа инициализации
И я помещаю этот слайд:
![enter image description here]()
Таким образом, для меня очень ясно, что делают столбцы инициализаторы Bean (это методы, аннотированные с помощью аннотации @PostContruct и которые автоматически вызывается сразу после методы setter (поэтому после инъекции dependecy), и я знаю, что я могу использовать для выполнения некоторой партии инициализации (как заполнение кеша, как в предыдущем примере).
Но что именно представляет собой следующий пост-процессор Bean? Что означает, что они выполняются до или после фазы инициализации?
Итак, мой Bean создается и выполняется инъекция зависимостей, поэтому фаза инициализации выполняется (путем выполнения аннотированного метода @PostContruct). Что означает, что пост-процессор Bean выполняется до фазы инициализации? Это означает, что это произойдет до выполнения @PostContruct аннотированного метода? Таким образом, int означает, что это может произойти до инъекции зависимостей (до этого вызываются методы setter)?
И что именно означает, что он выполняется после шага инициализации. Это означает, что после этого происходит exectuon метода @PostContruct, или что?
Я легко могу понять в голове, почему мне нужен метод @PostContruct, но я не могу представить типичный пример другого типа почтового процессора Bean, можете ли вы показать мне некоторые типичный пример использования?
Тпх
Ответы
Ответ 1
Spring doc объясняет BPP в настройке beans с помощью BeanPostProcessor. BPP beans - это особый вид beans, который создается перед любым другим beans и взаимодействует с вновь созданным beans. С помощью этой конструкции 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, и когда именно метод вызывается, проверьте docs
postProcessBeforeInitialization (Object bean, String beanName) Применить этот BeanPostProcessor для данного нового экземпляра bean перед любым beanобратные вызовы инициализации (например, InitializingBean afterPropertiesSet или пользовательский init-метод).
postProcessAfterInitialization (Object bean, String beanName) Применить этот BeanPostProcessor для данного нового экземпляра bean после любого beanобратные вызовы инициализации (например, InitializingBean afterPropertiesSet или пользовательский init-метод).
Важным битом является также, что
bean уже будет заполнен значениями свойств.
Что касается отношения с @PostConstruct
, обратите внимание, что это аннотирование является удобным способом объявления метода postProcessAfterInitialization
, и Spring узнает об этом, когда вы либо регистром CommonAnnotationBeanPostProcessor
, либо укажите <context:annotation-config />
в файле конфигурации bean. Будет ли метод @PostConstruct
выполняться до или после любого другого postProcessAfterInitialization
зависит от свойства order
Вы можете настроить несколько экземпляров BeanPostProcessor, и вы можете контролируйте порядок выполнения этих BeanPostProcessors, установив свойство order.
Ответ 2
Типичным примером для постпроцессора bean является то, когда вы хотите обернуть исходный bean в экземпляр прокси, например. при использовании аннотации @Transactional
.
Почтовый процессор bean будет передан исходный экземпляр bean, он может вызывать любые методы на целевом объекте, но он также получает возможность вернуть фактический экземпляр bean, который должен быть связан в контексте приложения, что означает, что он может фактически вернуть любой объект, который он хочет. Типичным сценарием, когда это полезно, является то, что почтовый процессор bean переносит цель в экземпляр прокси. Все вызовы в интерфейсе bean, связанные в контексте приложения, будут проходить через прокси-сервер, а затем прокси-сервер сможет выполнить некоторую магию до и/или после вызова на целевой bean, например. AOP или управление транзакциями.