阅读源码有利于陶冶情操,承接前文Spring源码情操陶冶-AbstractApplicationContext#postProcessBeanFactory

约定:web.xml中配置的contextClassXmlWebApplicationContext

瞧瞧官方注释

	/**
* Instantiate and invoke all registered BeanFactoryPostProcessor beans,
* respecting explicit order if given.
* <p>Must be called before singleton instantiation.必须在单例实例化前调用
*/

主要是实例化和调用所有已注册的BeanFactoryPostProcessors beans

源码简析

对应的代码清单如下

	//通过一个委托类来处理实例化调用
protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());
}

PostProcessorRegistrationDelegate#invokeBeanFactoryPostProcessors

简单的看下委托类中的此方法源码,代码清单如下

public static void invokeBeanFactoryPostProcessors(
ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) { // 第一步,Invoke BeanDefinitionRegistryPostProcessors first, if any.
Set<String> processedBeans = new HashSet<String>();
//条件满足
if (beanFactory instanceof BeanDefinitionRegistry) {
BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
List<BeanFactoryPostProcessor> regularPostProcessors = new LinkedList<BeanFactoryPostProcessor>();
List<BeanDefinitionRegistryPostProcessor> registryPostProcessors =
new LinkedList<BeanDefinitionRegistryPostProcessor>();
//刚开始进来beanFactoryPostProcessors为空
for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {
//BeanDefinitionRegistryPostProcessor目前该接口的实现者为MapperScannerConfigurer/ConfigurationClassPostProcessor
if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
BeanDefinitionRegistryPostProcessor registryPostProcessor =
(BeanDefinitionRegistryPostProcessor) postProcessor;
//调用postProcessBeanDefinitionRegistry接口,比如MapperScannerConfigurer则会进行扫描注册接口bean操作
registryPostProcessor.postProcessBeanDefinitionRegistry(registry);
registryPostProcessors.add(registryPostProcessor);
}
else {
regularPostProcessors.add(postProcessor);
}
} // Do not initialize FactoryBeans here: We need to leave all regular beans
// uninitialized to let the bean factory post-processors apply to them!
// Separate between BeanDefinitionRegistryPostProcessors that implement
// PriorityOrdered, Ordered, and the rest.
//寻找实现了BeanDefinitionRegistryPostProcessor接口类的beans
String[] postProcessorNames =
beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false); // First, invoke the BeanDefinitionRegistryPostProcessors that implement PriorityOrdered.这里只有ConfigurationClassPostProcessor类才操作
List<BeanDefinitionRegistryPostProcessor> priorityOrderedPostProcessors = new ArrayList<BeanDefinitionRegistryPostProcessor>();
for (String ppName : postProcessorNames) {
if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
priorityOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
processedBeans.add(ppName);
}
}
***
省略部分代码
*** // Now, invoke the postProcessBeanFactory callback of all processors handled so far.
invokeBeanFactoryPostProcessors(registryPostProcessors, beanFactory);
invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);
} else {
// Invoke factory processors registered with the context instance.
invokeBeanFactoryPostProcessors(beanFactoryPostProcessors, beanFactory);
} //第二步,处理注册在bean工厂中BeanFactoryPostProcessor接口实现类并调用公用的方法,比如PropertyResourceConfigurer资源文件解析类
String[] postProcessorNames =
beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false); // Separate between BeanFactoryPostProcessors that implement PriorityOrdered,
// Ordered, and the rest. 执行的优先权
List<BeanFactoryPostProcessor> priorityOrderedPostProcessors = new ArrayList<BeanFactoryPostProcessor>();
List<String> orderedPostProcessorNames = new ArrayList<String>();
List<String> nonOrderedPostProcessorNames = new ArrayList<String>();
for (String ppName : postProcessorNames) {
if (processedBeans.contains(ppName)) {
// skip - already processed in first phase above
}
else if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
priorityOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanFactoryPostProcessor.class));
}
else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
orderedPostProcessorNames.add(ppName);
}
else {
nonOrderedPostProcessorNames.add(ppName);
}
} ***
省略部分代码
***
}

主要功能是对实现BeanFactoryPostProcessor的bean类进行调用公共接口方法postProcessBeanFactory,并相关的信息可关联至ConfigurableListableBeanFactorybeanFactory。常见的使用类为PropertyPlaceholderConfigurer文件解析类、MapperScannerConfigurer SQL接口注册类。公共接口的调用前者会对每个bean对象含有${}进行解析替换,后者会注册mapper class接口类并尝试解析注解

下节预告

Spring源码情操陶冶-AbstractApplicationContext#registerBeanPostProcessors

Spring源码情操陶冶-AbstractApplicationContext#invokeBeanFactoryPostProcessors的更多相关文章

  1. Spring源码情操陶冶-AbstractApplicationContext#registerBeanPostProcessors

    承接前文Spring源码情操陶冶-AbstractApplicationContext#invokeBeanFactoryPostProcessors 瞧瞧官方注释 /** * Instantiate ...

  2. Spring源码情操陶冶-AbstractApplicationContext#postProcessBeanFactory

    阅读源码有利于陶冶情操,承接前文Spring源码情操陶冶-AbstractApplicationContext#prepareBeanFactory 约定:web.xml中配置的contextClas ...

  3. Spring源码情操陶冶-AbstractApplicationContext#finishBeanFactoryInitialization

    承接前文Spring源码情操陶冶-AbstractApplicationContext#registerListeners 约定web.xml配置的contextClass为默认值XmlWebAppl ...

  4. Spring源码情操陶冶-AbstractApplicationContext#registerListeners

    承接前文Spring源码情操陶冶-AbstractApplicationContext#onRefresh 约定web.xml配置的contextClass为默认值XmlWebApplicationC ...

  5. Spring源码情操陶冶-AbstractApplicationContext#onRefresh

    承接前文Spring源码情操陶冶-AbstractApplicationContext#initApplicationEventMulticaster 约定web.xml配置的contextClass ...

  6. Spring源码情操陶冶-AbstractApplicationContext#initApplicationEventMulticaster

    承接前文Spring源码情操陶冶-AbstractApplicationContext#initMessageSource 约定web.xml配置的contextClass为默认值XmlWebAppl ...

  7. Spring源码情操陶冶-AbstractApplicationContext#initMessageSource

    承接前文Spring源码情操陶冶-AbstractApplicationContext#registerBeanPostProcessors 约定web.xml配置的contextClass为默认值X ...

  8. Spring源码情操陶冶-AbstractApplicationContext#prepareBeanFactory

    阅读源码有助于陶冶情操,本文承接Spring源码情操陶冶-AbstractApplicationContext#obtainFreshBeanFactory 瞧瞧官方注释 /** * Configur ...

  9. Spring源码情操陶冶-AbstractApplicationContext#obtainFreshBeanFactory

    前言-阅读源码有利于陶冶情操,本文承接前文Spring源码情操陶冶-AbstractApplicationContext 约束: 本文指定contextClass为默认的XmlWebApplicati ...

随机推荐

  1. post和get方式区别

    Ajax中我们经常用到get和post请求.那么什么时候用get请求,什么时候用post方式请求呢? 在做回答前我们首先要了解get和post的区别.1. get是把参数数据队列加到提交表单的ACTI ...

  2. html之改变图片透明度而不改变文字的透明度--两种方法实现

    图片与图片上的文字设置不同的透明度的两种方法: 第一种方法:背景图+定位+background: url(timg.jpg)no-repeat; <!DOCTYPE html> <h ...

  3. java中的选择排序之降序排列

    import java.util.Arrays;//必须加载 class Demo{ public static void main(String []args){ int[] arr={3,54,4 ...

  4. 4.vbs的循环,switch,判断等语句

    1.条件判断语句 If Then Else Sub judge(x) Then MsgBox "the num is 0" Then MsgBox "the num is ...

  5. PILLOW图片中加入中文 曲线救国Opencv

    索引 简述 准备 示例 效果图 结语 简述 我在使用opencv2或3的时候想要在图片上添加中文文字,需要去下载Freetype库,编译好链接到opencv库中才能中文的输出.网上大部分在图片中插入中 ...

  6. 【知识整理】这可能是最好的RxJava 2.x 入门教程(五)

    这可能是最好的RxJava 2.x入门教程系列专栏 文章链接: 这可能是最好的RxJava 2.x 入门教程(一) 这可能是最好的RxJava 2.x 入门教程(二) 这可能是最好的RxJava 2. ...

  7. Linux之正则表达式

    正则表达式与通配符的区别: 最常应用正则表达式的命令是grep(egrep),sed,awk. 正则表达式和通配符有本质区别,正则表达式用来找:[文件]内容,文本,字符串.一般只有三剑客支持.通配符用 ...

  8. Spring Security Filter详解

    Spring Security Filter详解 汇总 Filter 作用 DelegatingFilterProxy Spring Security基于这个Filter建立拦截机制 Abstract ...

  9. 使用 Live555 搭建流媒体服务器

    最近因为工作需要,需要搭建流媒体服务器,所以研究了一下,在此分享我的搭建过程. 搭建过程还是非常简单的! 搭建环境为Centos 7.2 64bit 一.安装gcc编译器 yum install gc ...

  10. (转载)Oracle10g 数据泵导出命令 expdp 使用总结(一)

    原文链接:http://hi.baidu.com/edeed/item/890626ef6f6d9d265b2d646f Oracle10g 数据泵导出命令 expdp 使用总结(二)Oracle10 ...