Spring源码情操陶冶-AbstractApplicationContext#invokeBeanFactoryPostProcessors
阅读源码有利于陶冶情操,承接前文Spring源码情操陶冶-AbstractApplicationContext#postProcessBeanFactory
约定:web.xml中配置的contextClass为XmlWebApplicationContext
瞧瞧官方注释
/**
* 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的更多相关文章
- Spring源码情操陶冶-AbstractApplicationContext#registerBeanPostProcessors
承接前文Spring源码情操陶冶-AbstractApplicationContext#invokeBeanFactoryPostProcessors 瞧瞧官方注释 /** * Instantiate ...
- Spring源码情操陶冶-AbstractApplicationContext#postProcessBeanFactory
阅读源码有利于陶冶情操,承接前文Spring源码情操陶冶-AbstractApplicationContext#prepareBeanFactory 约定:web.xml中配置的contextClas ...
- Spring源码情操陶冶-AbstractApplicationContext#finishBeanFactoryInitialization
承接前文Spring源码情操陶冶-AbstractApplicationContext#registerListeners 约定web.xml配置的contextClass为默认值XmlWebAppl ...
- Spring源码情操陶冶-AbstractApplicationContext#registerListeners
承接前文Spring源码情操陶冶-AbstractApplicationContext#onRefresh 约定web.xml配置的contextClass为默认值XmlWebApplicationC ...
- Spring源码情操陶冶-AbstractApplicationContext#onRefresh
承接前文Spring源码情操陶冶-AbstractApplicationContext#initApplicationEventMulticaster 约定web.xml配置的contextClass ...
- Spring源码情操陶冶-AbstractApplicationContext#initApplicationEventMulticaster
承接前文Spring源码情操陶冶-AbstractApplicationContext#initMessageSource 约定web.xml配置的contextClass为默认值XmlWebAppl ...
- Spring源码情操陶冶-AbstractApplicationContext#initMessageSource
承接前文Spring源码情操陶冶-AbstractApplicationContext#registerBeanPostProcessors 约定web.xml配置的contextClass为默认值X ...
- Spring源码情操陶冶-AbstractApplicationContext#prepareBeanFactory
阅读源码有助于陶冶情操,本文承接Spring源码情操陶冶-AbstractApplicationContext#obtainFreshBeanFactory 瞧瞧官方注释 /** * Configur ...
- Spring源码情操陶冶-AbstractApplicationContext#obtainFreshBeanFactory
前言-阅读源码有利于陶冶情操,本文承接前文Spring源码情操陶冶-AbstractApplicationContext 约束: 本文指定contextClass为默认的XmlWebApplicati ...
随机推荐
- linux-ubuntu下fastQC的安装
1.fastqc是在Java环境下运行的:所以在安装fastqc之前,Linux下要有相应的Java运行环境(JRE).且java的版本应该在1.8.0版以上 2.java的安装:下载最新版本的Jav ...
- badboy录制兼容性有趣测试
badboy录制默认是启动IE浏览器,使用badboy录制脚本时,遇到测试系统对IE浏览器不兼容时,就需要考虑换浏览器,修改为其他浏览器(如firefox.chrome)录制,只需要设置该浏览器为默认 ...
- Java类的装载过程和静态代码块
在Java中,类装载器把一个类装入Java虚拟机中,要经过三个步骤来完成:装载.连接和初始化,其中连接又可以分成校验.准备和解析三步,除了解析外,其它步骤是严格按照顺序完成的,各个步骤的主要工作如下: ...
- 蜘蛛大战之 站点LOGO(SEO)
起因: 同事让我看 搜公司名称,百度第一位并没有出现公司网址,是别人的,然后我 惊奇的发现,站点logo 竟然 抓了张 无关紧要的图片,从此 变开始了 为期 10天+的战争: 经过: [2017-06 ...
- Thinkphp中的内置标签用法
Thinkphp中的内置标签有:Volist,Foreach,For,Switch,比较标签,范围判断标签,IF,Present,Empty,Defined,Assign,Define,标签嵌套,im ...
- 移动端响应式布局+rem+calc()
1.媒体查询:@media only screen and (max-width: ) {},在最初做pc端时,使用各种媒体查询,因为pc的屏幕分辨率总共就几种,不嫌麻烦的重复使用类名.有很大的缺陷就 ...
- Spring boot 1: 使用IDEA创建Spring boot项目
项目用到的环境: Windows 10 JDK8 IntelliJ IDEA 2017.1.3 Apache Tomcat 8 Maven 3.3.3 使用IDEA新建spring boot项目 新建 ...
- redmine测试使用小结
在尽量不影响当前项目活动的情况下,可以对测试过程作部分改进,能够支持建立项目的BUG管理过程,简述如下: 1.配置角色和权限->新建角色:测试人员 (1)主要配置问题跟踪权限 (2)提前规划好再 ...
- CSS3学习系列之盒样式(一)
盒的基本类型 在css中,使用display属性来定义盒的类型,总体上来说,css中的盒分为block类型与inline类型 inline-block类型 inline-block类型是在css2.1 ...
- BigDecimal四舍五入使用总结
//BigDecimal四舍五入double f1 = new BigDecimal(1).setScale(2,RoundingMode.HALF_UP).doubleValue();//转化成字符 ...