Как именно работает весенний BeanPostProcessor?

Я учусь на сертификацию Spring Core, и у меня есть некоторые сомнения в том, как весной обрабатывать жизненный цикл бобы и, в частности, о бин пост процессор.

Так у меня есть эта схема:

enter image description here

для меня довольно ясно, что это значит:

следующие шаги происходят в Загрузить Определения Bean фаза:

  • в @Configuration классы обрабатываются и/или @Components несколько отсканировано и / или XML-файлы разбираются.

  • определения Bean добавлены в BeanFactory (каждый индексируется под своим идентификатором)

  • специальные BeanFactoryPostProcessor beans вызывается, он может изменить определение любого bean (например, для замены значений-заполнителей свойств).

затем следующие шаги происходят в этап создания зерен:

  • каждый боб по умолчанию охотно создается (создается в правильном порядке с введенными зависимостями).

  • после инъекции зависимостей каждый боб проходит постобработку фаза, на которой может произойти дальнейшая настройка и инициализация.

  • после обработки зерен полностью инициализирован и готов к использованию (отслеживается его id, пока контекст не будет уничтожен)

хорошо, это довольно ясно для меня, и я также знаю, что существует два типа бобовых почтовых процессоров которых:

  • инициализаторов: инициализируйте компонент, если указано (т. е. @PostConstruct).

  • и все остальные:, которые позволяют дополнительно настраивать и может выполняться до или после инициализации шаг

и я публикую этот слайд:

enter image description here

Так что для меня очень ясно, что делает инициализаторы бобовые почтовые процессоры (это методы, аннотированные @PostContruct аннотации и которые автоматически вызываются сразу после методов сеттера (поэтому после инъекции зависимостей), и я знаю, что могу использовать для выполнения некоторого пакета инициализации (как заполнить кэш, как в предыдущем образец.)

но что именно представляет собой другой процессор Bean post? Что мы имеем в виду, когда говорим, что эти шаги выполняются до или после фазы инициализации?

таким образом, мои бобы создаются и его зависимости вводятся, поэтому фаза инициализации завершается (путем выполнения @PostContruct аннотированный метод). Что мы имеем в виду, говоря, что постпроцессор Bean используется до фазы инициализации? Он означает, что это происходит перед @PostContruct аннотированное выполнение метода? Означает ли это, что это может произойти до инъекции зависимостей (до этого вызываются методы setter)?

и что именно мы имеем в виду, когда говорим, что это выполняется после шага инициализации. Это означает, что после этого происходит выполнение a @PostContruct аннотированный метод, или что?

Я могу легко понять, почему я нужен @PostContruct аннотированный метод, но я не могу понять типичный пример другого типа постпроцессора bean, можете ли вы показать мне типичный пример того, когда используются?

3 ответов


Spring doc объясняет BPPs под настройка бобов с помощью 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 для каждого создал Боб.

чтобы понять, как метод соответствует жизненному циклу компонента, и когда именно метод вызывается, проверьте docs

postProcessBeforeInitialization (объект bean, строка beanName) применить этот BeanPostProcessor для данного нового экземпляра bean перед любым bean обратные вызовы инициализации (например, afterPropertiesSet InitializingBean или пользовательский init-метод).

postProcessAfterInitialization (объект bean, строка beanName) применить этот BeanPostProcessor данной новой бобовый экземпляр после любых бобовых обратные вызовы инициализации (например, afterPropertiesSet InitializingBean или пользовательский init-метод).

важным моментом также является то, что

компонент уже будет заполнен значениями свойств.

ибо что касается отношения с @PostConstruct обратите внимание, что эта аннотация является удобным способом объявления postProcessAfterInitialization метод, и весна узнает об этом, когда вы либо регистрируетесьCommonAnnotationBeanPostProcessor или указать <context:annotation-config /> в файле конфигурации bean. Ли @PostConstruct метод будет выполняться до или после любого другого postProcessAfterInitialization зависит от order свойства

вы можете настроить несколько экземпляров BeanPostProcessor, и вы можете управляйте порядком, в котором эти BeanPostProcessors выполняются, задавая порядок свойство.


типичным примером для постпроцессора bean является то, когда вы хотите обернуть исходный bean в экземпляр прокси, например, при использовании @Transactional Примечание.

обработчику Bean post будет передан исходный экземпляр bean, он может вызывать любые методы на цели, но он также возвращает фактический экземпляр bean, который должен быть связан в контексте приложения, что означает, что он может фактически вернуть любой объект, который он хочет. Типичный сценарий, когда это полезно когда почтовый процессор bean обертывает цель в экземпляре прокси-сервера. Все вызовы на бобе, связанном в контексте приложения, будут проходить через прокси-сервер, и прокси-сервер затем выполнит некоторую магию до и/или после вызовов на целевом Бобе, например AOP или управление транзакциями.


разница составляет BeanPostProcessor подключится к инициализации контекста, затем вызовет postProcessBeforeInitialization и postProcessAfterInitialization для всех определенных зерен.

но @PostConstruct используется только для определенного класса, который вы хотите настроить создание компонента после конструктора или метода set.