在《Spring的IOC的源码解析(一)》中完成了BeanDefinition的解析和加载,下边会接着分析bean的PostProcessor
一、准备一些公共的对象
逻辑都在这句代码中:
prepareBeanFactory(beanFactory);
主要操作有:设置类加载器,设置EL表达式处理器,编辑器,Aware接口处理器,注册自动装配类,设置LTW ware bean的BPP,注册环境bean
这里一共这设置了3个公共的BPP:
ApplicationContextAwareProcessor
ApplicationListenerDetector
LoadTimeWeaverAwareProcessor
二、BFPP的实例化和执行
在BeanDefinition的解析和加载过程中,如果也设置了BFPP bean,这些bean将在这里实例化和执行
// Invoke factory processors registered as beans in the context.
invokeBeanFactoryPostProcessors(beanFactory);
从bean容器中获取BFPP BeanDefinition的方法:
beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
首先处理的是BeanDefinitionRegistryPostProcessor.class Bean
然后处理,其他BeanFactoryPostProcessor.class Bean
beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);
BFPP bean实例化的方法是:
beanFactory.getBean(ppName, BeanFactoryPostProcessor.class);
对每一个BFPP对象,都要执行postProcessBeanFactory方法:
postProcessor.postProcessBeanFactory(beanFactory);
三、BPP的实例化
// Register bean processors that intercept bean creation.
用于在bean的创建过程中,拦截以及AOP代理实现
registerBeanPostProcessors(beanFactory);
//初始化BPP并注册到工程中
首先,获取BPP的BeanDefinition:
beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false);
BPP BeanDefinition一般在其他bean标签的解析过程中设置到容器中;
例如<aop:config>会设置尝试设置
AspectJAwareAdvisorAutoProxyCreator
;
实例化的代码:
beanFactory.getBean(ppName, BeanPostProcessor.class);
最后,注册BPP,这里注册就是把BPP对象放到beanFactory的属性beanPostProcessors中,方便getBean方法中使用;
final List<BeanPostProcessor> beanPostProcessors = new ArrayList<>();
for (BeanPostProcessor postProcessor : postProcessors) {
beanFactory.addBeanPostProcessor(postProcessor);
}
注意,在bean容器的初始化过程中,ApplicationContextAwareProcessor,ApplicationListenerDetector,LoadTimeWeaverAwareProcessor这3个BPP是先于所有的BFPP初始化的,但是他们的初始化是主动的,使用Java的new关键字。
3.初始化non-lazy-init的bean
finishBeanFactoryInitialization(beanFactory);
首先,实例化
LoadTimeWeaverAware类型的bean
,公共的BPP LoadTimeWeaverAwareProcessor会为这些bean 对象设置loadTimeWeaver属性;
loadTimeWeaver属性的值分析见《load-time-weaver标签的解析》
String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);
for (String weaverAwareName : weaverAwareNames) {
getBean(weaverAwareName);
}
然后,处理non-lazy-init的单例模式bean,非单例模式的bean不用提前注册。
if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
getBean(beanName);
}
关于getBean()方法,即bean的实例化过程,参看《Spring的IOC的源码解析(三)》。