阅读源码有利于陶冶情操,承接前文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. thinkphp5.0学习笔记(三)获取信息,变量,绑定参数

    1.构造函数: 控制器类必须继承了\think\Controller类,才能使用: 方法_initialize 代码: <?php namespace app\lian\controller; ...

  2. 一些java方面面试题,没事做做看看(带答案)

    1. Switch能否用string做参数? a.在?Java? <http://lib.csdn.net/base/java>7 之前, switch 只能支持byte,short,ch ...

  3. 如何远程调试zookeeper集群

    我们在阅读一些源码的时候,如果能调试源代码将会大大的提高我们的阅读效率.最近在学习zookeeper源码,分享下如何调试zookeeper集群. zookeeper代码,调试环境搭建 1.下载zook ...

  4. Sql行列转换参考

    行列转换:SELECT max(case type when 0 then jine else 0 end) a,max(case type when 1 then jine else 0 end) ...

  5. vue-cli 脚手架 安装

    一. node安装 1)如果不确定自己是否安装了node,可以在命令行工具内执行: node -v  (检查一下 版本): 2)如果 执行结果显示: xx 不是内部命令,说明你还没有安装node , ...

  6. 两种代理模式(JDK和Cglib)实例

    CGlib代理模式: package CGLIB; import java.lang.reflect.Method; import JDK.Test; import net.sf.cglib.prox ...

  7. 【转】JS容器拖拽效果,并通过cookie保存拖拽各容器的所在位置

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  8. NavigationView的头部的事件监听

    现在App的UI设计中Drawerlayout+NavigationView是一个比较常用的设计了,而以前我一般只是在Navigation中的menu(即下部的item中)添加事件监听,而今天碰到一个 ...

  9. 基于Dapper的分页实现,支持筛选,排序,结果集总数,非存储过程

    简介 之前事先搜索了下博客园上关于Dapper分页的实现,有是有,但要么是基于存储过程,要么支持分页,而不支持排序,或者搜索条件不是那么容易维护. 代码 首先先上代码: https://github. ...

  10. Oracle 左连接 left join、右连接right join说明

    Oracle 左.右连接 + 在等号 左边表示右连接  获取右表所有记录,即使左表没有对应匹配的记录. + 在等号 右边表示左连接  获取左表所有记录,即使右表没有对应匹配的记录. 例子: selec ...