深入理解Spring源码(5)-- invokeBeanFactoryPostProcessors(2)

63 阅读2分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第3天,点击查看活动详情

前文已经简单的说明了invokeBeanFactoryPostProcessors的源码,下面看下具体的细节实现以及扩展实现

首先处理的beanFactoryPostProcessors怎么才能有值?

我们执行默认的ClassPathXmlApplicationContext到invokeBeanFactoryPostProcessors中时,beanFactoryPostProcessors默认为空,那么怎么才能让这里有值呢?

可以看到beanFactoryPostProcessors是从getBeanFactoryPostProcessors()方法中获得的

image.png

但是这个方法中是直接返回了this.beanFactoryPostPrcessors

image.png

根据经验可以推断出在这个类中应该会有一个add或者set的方法来添加beanFactoryPostProcessors,找到了这个方法

image.png

下面来实现beanFactoryPostProcessors的添加

添加beanFactoryPostProcessors

首先准备一个类MyClassPathXmlApplicationContext,并使这个类继承ClassPathXmlApplicationContext

我们可以重写一下addBeanFactoryPostProcessor方法

image.png

执行一下

image.png

哎😌,很奇怪的是这里的beanFactoryPostProcessors并没有加载进来,其实这个问题很简单,我们虽然重写了addBeanFactoryPostProcessors方法,但是没有地方执行啊,所以自然而已就没有加载进来。那么怎么可以让他加载进来呢,首先,需要在invokeBeanFactoryPostProcessors方法执行前去调用addBeanFactoryPostProcessor的方法即可。

那么找一下尝试下

可以发现有这么几个地方貌似可以执行

1、在prepareRefresh()方法中initPropertySources()方法中执行(虽然这个方法官方描述是初始化上下文环境中的任何占位符属性源,但是我们可以在这里尝试下)
2、refreshBeanFactory()中的customizeBeanFactory()方法
3、postProcessBeanFactory(beanFactory)方法

下面一个一个试一下
一、prepareRefresh()方法中initPropertySources()

image.png

结果:

image.png

可以看到已经成功的添加进来

二、refreshBeanFactory()中的customizeBeanFactory()

image.png

结果:\

image.png

同样是没问题的

三、postProcessBeanFactory(beanFactory)

image.png

结果:\

image.png

可以添加进来

综上,三种方式均可以将beanFactoryPostProcessors添加进来