0
点赞
收藏
分享

微信扫一扫

【Spring(七)】BeanFactoryPostProcessor


先回顾下spring高级容器中最重要的方法refresh:

先构建一个DefaultListableBeanFactory容器实例,内部会注册一次bean;

再调用postProcessBeanFactory方法及invokeBeanFactoryPostProcessors方法,这里是spring的一个扩展点:BeanFactoryPostProcessor接口。因为之前已经注册过一次bean定义了,这里留了一个扩展点,可以补充bean定义也可以修改之前的bean定义。spring中对于@Configuration处理就是使用BeanFactoryPostProcessor的经典案例。

注意BeanFactoryPostProcessor是用于处理bean定义的注册的,而非bean的实例化。

再往后,registerBeanPostProcessors注册beanPostProcessor;

然后是一些国际化;

再往后,finishBeanFactoryInitialization完成非lazy的bean的实例化,里面会调用beanpostprocessor来处理bean的实例化,也是一个扩展点。Spring的@PostConstruct是一个经典例子。

这里主要看下BeanFactoryPostProcessor。

一个小例子:

public class TestBeanFactoryProcessor implements BeanFactoryPostProcessor {
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
String[] names = beanFactory.getBeanDefinitionNames();
for (String name : names) {
System.out.println(name);
}
}
}

仅仅打印出当前注册的bean的名字。

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean class="spring.xml.config.TestBeanFactoryProcessor"/>
</beans>

注册该processor。

结果:

cd3
player3
player4
spring.xml.config.TestBeanFactoryProcessor#0

这里没有贴bean的定义。

 

再看下原理:

refresh的invokeBeanFactoryPostProcessors方法会加载容器内的processor:

protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());
}

invoke方法的核心逻辑:

String[] postProcessorNames =beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);


/**
* Invoke the given BeanFactoryPostProcessor beans.
*/
private static void invokeBeanFactoryPostProcessors(
Collection<? extends BeanFactoryPostProcessor> postProcessors, ConfigurableListableBeanFactory beanFactory) {

for (BeanFactoryPostProcessor postProcessor : postProcessors) {
postProcessor.postProcessBeanFactory(beanFactory);
}
}

从容器中加载processor,再逐个调用接口方法。

举报

相关推荐

0 条评论